merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

pg_insert_transfer.sql (3253B)


      1 --
      2 -- This file is part of TALER
      3 -- Copyright (C) 2026 Taler Systems SA
      4 --
      5 -- TALER is free software; you can redistribute it and/or modify it under the
      6 -- terms of the GNU General Public License as published by the Free Software
      7 -- Foundation; either version 3, or (at your option) any later version.
      8 --
      9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11 -- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 --
     13 -- You should have received a copy of the GNU General Public License along with
     14 -- TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 --
     16 
     17 DROP FUNCTION IF EXISTS merchant_do_insert_transfer;
     18 CREATE FUNCTION merchant_do_insert_transfer (
     19   IN in_instance_id TEXT,
     20   IN in_exchange_url TEXT,
     21   IN in_wtid BYTEA,
     22   IN in_credit_amount taler_amount_currency,
     23   IN in_credited_account_payto TEXT,
     24   IN in_bank_serial_id INT8, -- can be NULL if unknown
     25   IN in_execution_time INT8,
     26   OUT out_no_instance BOOL,
     27   OUT out_no_account BOOL,
     28   OUT out_conflict BOOL)
     29 LANGUAGE plpgsql
     30 AS $$
     31 DECLARE
     32   my_merchant_id INT8;
     33   my_account_serial INT8;
     34   my_record RECORD;
     35   my_bank_serial_id INT8;
     36   my_credit_amount taler_amount_currency;
     37 BEGIN
     38 
     39 out_conflict=FALSE;
     40 
     41 -- Which instance are we using?
     42 SELECT merchant_serial
     43   INTO my_merchant_id
     44   FROM merchant_instances
     45  WHERE merchant_id=in_instance_id;
     46 IF NOT FOUND
     47 THEN
     48   out_no_instance=TRUE;
     49   out_no_account=TRUE; -- also true...
     50   RETURN;
     51 END IF;
     52 out_no_instance=FALSE;
     53 
     54 SELECT account_serial
     55   INTO my_account_serial
     56   FROM merchant_accounts
     57  WHERE REGEXP_REPLACE(payto_uri,
     58                       '\\?.*','')
     59       =REGEXP_REPLACE(in_credited_account_payto,
     60                       '\\?.*','')
     61    AND merchant_serial=my_merchant_id;
     62 IF NOT FOUND
     63 THEN
     64   out_no_account=TRUE;
     65   RETURN;
     66 END IF;
     67 out_no_account=FALSE;
     68 
     69 SELECT bank_serial_id
     70       ,credit_amount
     71   INTO my_record
     72   FROM merchant_transfers
     73  WHERE wtid=in_wtid
     74    AND account_serial=my_account_serial
     75    AND exchange_url=in_exchange_url;
     76 IF NOT FOUND
     77 THEN
     78   INSERT INTO merchant_transfers
     79     (exchange_url
     80     ,wtid
     81     ,credit_amount
     82     ,account_serial
     83     ,bank_serial_id
     84     ,execution_time
     85     ) VALUES
     86     (in_exchange_url
     87     ,in_wtid
     88     ,in_credit_amount
     89     ,my_account_serial
     90     ,in_bank_serial_id
     91     ,in_execution_time);
     92   -- Do notify on TALER_DBEVENT_MERCHANT_WIRE_TRANSFER_CONFIRMED
     93   NOTIFY XJ5N652FA4TBS2WXGY3S1FMPMQYTD8KAZA9B7HW9JWJ4PZ2DB852G;
     94   RETURN;
     95 END IF;
     96 
     97 my_bank_serial_id = my_record.bank_serial_id;
     98 my_credit_amount = my_record.credit_amount;
     99 
    100 IF ( (in_credit_amount.val  != my_credit_amount.val)  OR
    101      (in_credit_amount.frac != my_credit_amount.frac) OR
    102      (in_credit_amount.curr != my_credit_amount.curr) )
    103 THEN
    104   out_conflict = TRUE; -- amounts differ, not OK!
    105   RETURN;
    106 END IF;
    107 
    108 IF ( (my_bank_serial_id IS NULL) AND
    109      (in_bank_serial_id IS NOT NULL) )
    110 THEN
    111   -- We learned the bank_bank_serial_id, update that
    112   UPDATE merchant_transfers
    113      SET bank_serial_id=in_bank_serial_id
    114    WHERE wtid=in_wtid
    115      AND account_serial=my_account_serial
    116      AND exchange_url=in_exchange_url;
    117   RETURN;
    118 END IF;
    119 
    120 -- idempotent request, success.
    121 
    122 END $$;