-- Deploy camper:redsys_sign_request to pg
-- requires: roles
-- requires: extension_pgcrypto
-- requires: schema_camper
-- requires: encode_base64url
-- requires: redsys_encrypt
-- requires: redsys_request
-- requires: redsys_signed_request
-- requires: company
-- requires: currency
-- requires: language

begin;

set search_path to camper, public;

create or replace function redsys_sign_request(company_id integer, request redsys_request) returns redsys_signed_request as
$$
	select row(
		merchant_parameters,
		encode(hmac(
			convert_to(merchant_parameters, 'UTF-8'),
			redsys_encrypt(company_id, convert_to((request).order_number, 'UTF-8')),
			'sha256'
		), 'base64'),
		'HMAC_SHA256_V1'
	)
	from (
		select encode_base64url(
			convert_to(
				-- not using JSONB because for unit test i need stable key order
				json_build_object(
					'Ds_Merchant_MerchantCode', merchant_code,
					'Ds_Merchant_Terminal', terminal_number::text,
					'Ds_Merchant_MerchantName', business_name,
					'Ds_Merchant_TransactionType', (request).transaction_type::text,
					'Ds_Merchant_Amount', parse_price((request).amount, decimal_digits)::text,
					'Ds_Merchant_Currency', currency.redsys_code::text,
					'Ds_Merchant_Order', (request).order_number,
					'Ds_Merchant_Productdescription', (request).product,
					'Ds_Merchant_Titular', (request).card_holder,
					'Ds_Merchant_UrlOK', (request).success_uri::text,
					'Ds_Merchant_UrlKO', (request).failure_uri::text,
					'Ds_Merchant_MerchantURL', (request).notification_uri::text,
					'Ds_Merchant_ConsumerLanguage', language.redsys_code::text
				)::text,
				'UTF-8'
			)
		) as merchant_parameters
		from redsys
			join company using (company_id)
			join currency using (currency_code)
		, language
		where redsys.company_id = redsys_sign_request.company_id
		  and language.lang_tag = (request).lang_tag
	) as build
	;
$$
	language sql
	stable
;

revoke execute on function redsys_sign_request(integer, redsys_request) from public;
grant execute on function redsys_sign_request(integer, redsys_request) to guest;
grant execute on function redsys_sign_request(integer, redsys_request) to employee;
grant execute on function redsys_sign_request(integer, redsys_request) to admin;

commit;
