-- Deploy camper:process_payment_response to pg -- requires: roles -- requires: schema_camper -- requires: redsys_response -- requires: payment -- requires: payment_redsys_response -- requires: parse_price -- requires: currency begin; set search_path to camper, public; create or replace function process_payment_response(payment_slug uuid, response redsys_response) returns text as $$ declare pid integer; next_status text; begin if response.transaction_type not in (0, 1, 2, 3, 9) then raise invalid_parameter_value using message = response.transaction_type || ' is not a processable transaction type'; end if; select payment_id into pid from payment where slug = payment_slug; if pid is null then return ''; end if; update payment set payment_status = case response.transaction_type when 0 then -- charge case when response.response_code < 100 then 'completed' else 'failed' end when 1 then -- authorization hold case when response.response_code < 100 then 'preauth' else 'failed' end when 2 then -- confirm authorization hold case when response.response_code = 900 then 'completed' else payment_status end when 3 then -- refund case when response.response_code = 900 then 'refunded' else payment_status end when 9 then -- void authorization hold case when response.response_code = 400 then 'voided' else payment_status end else payment_status end , updated_at = current_timestamp where payment_id = pid and ( (response.transaction_type in (0, 1) and payment_status in ('pending', 'failed')) or (response.transaction_type in (2, 9) and payment_status in ('preauth', 'failed')) or (response.transaction_type = 3 and payment_status = 'completed') ) returning payment_status into next_status; insert into payment_redsys_response ( payment_id , response_code , date_time , secure_payment , transaction_type , amount , currency_code , order_number , authorization_code , merchant_code , terminal_number , error_code ) select pid , response.response_code , response.date_time , response.secure_payment , response.transaction_type , parse_price(response.amount, decimal_digits) , response.currency_code , response.order_number , response.authorization_code , response.merchant_code , response.terminal_number , response.error_code from currency where currency.currency_code = response.currency_code ; return coalesce(next_status, ''); end; $$ language plpgsql ; revoke execute on function process_payment_response(uuid, redsys_response) from public; grant execute on function process_payment_response(uuid, redsys_response) to guest; grant execute on function process_payment_response(uuid, redsys_response) to employee; grant execute on function process_payment_response(uuid, redsys_response) to admin; commit;