Direct & Conditional Payments

Published on
January 16, 2022
Published by
G2C Team

Payments are one of the key features of Bitcoin, of course. Two of the payment methods that the G2C Suite supports are both peer-to-peer payments: direct payments and conditional payments. Let us describe each of them:

Direct payment

A direct payment is a payment that flows from a payer to a payee, immediately and without intermediaries. G2C library supports two different ways to send funds between two parties: with nicknames generated when users have been created or with the payee's Paymail.

Direct payment between two users using nicknames

In this particular peer-to-peer payment, both payer and payee are identified by their corresponding nicknames, those that have been resolved during the creation of both users. The payment is settled immediately: a payee will receive the funds as soon as the payer executes the transfer.

async directPayment() {
 return new Promise(async (resolve, reject) => {
   try {
       // directPaymentParameters object contains the following fields:
       // const directPaymentParameters = {
       //    tokenid,
       //    tokens1,
       //    tokenc1,
       //    application,
       //    sourcenick,
       //    destinationnick,
       //    amount,
       //    description,
       //    commissiontype,
       // }
       await g2cclient_walletDirectSend(directPaymentParameters, (response) => {
         if (response.hasOwnProperty('error')) {
           console.log('Error {}', error);
           reject(response.error);
         }
         console.log('Direct payment {}', response);
         resolve(response);
       });
   } catch (error) {
       console.log('Error {}', error);
       reject(new Error(error));
   }
 });
}

Direct payment to Paymail

It is a payment from a payer to a payee that is settled immediately. This way, a payee will receive the funds as soon as the payer executes the transfer using the payee's Paymail as a recipient of the funds.

async directPaymentPaymail() {
 return new Promise(async (resolve, reject) => {
   try {
     // paymailSendParameters object contains the following fields:
     // const paymailSendParameters = {
     //    tokenid,
     //    tokens1,
     //    tokenc1,
     //    application,
     //    sourcenick,
     //    destinationpaymail,
     //    amount,
     //    description,
     //    commissiontype,
     //  }
     await g2cclient_walletSendToPaymail(paymailSendParameters, (response) => {
       if (response.hasOwnProperty('error')) {
         console.log('Error {}', error);
         reject(response.error);
       }
       console.log('Direct payment {}', response);
       resolve(response);
     });
   } catch (error) {
       console.log('Error {}', error);
       reject(new Error(error));
   }
 });
}

Conditional payments

A conditional or deferred payment is a special method of payment in which the payer is committed to send an amount of money to the payee if and when a condition is met. The simplest condition is one in which the payee can either accept or reject the conditional payment emitted by a payer. This use case will be used to illustrate the next example.

Conditional propose

G2C library allows to call g2cclient_walletConditionalPropose() function to create a conditional payment proposal from a payer to a payee. Once configured, funds from the payer are locked until payee either accepts or rejects the payment or any other condition is met. At the same time, a paymentauth token is generated. This token must be stored safely since it contains critical information about the payment and it can be used only once to accept or reject the conditional payment.

async conditionalPaymentPropose() {
   return new Promise((resolve, reject) => {
     try {
       // proposeParameters object contains the following fields:
       // const proposeParameters = {
       //    application,
       //    tokenc1,
       //    tokenid,
       //    tokens1,
       //    sourcenick: from,
       //    destinationnick: to,
       //    amount,
       //    description,
       //    commissiontype,
       //  }
       g2cclient_walletConditionalPropose( proposeParameters, (response) => {
           if ( response.hasOwnProperty('error') ) {
             console.log('Error {}', error);
             return reject(Error(response.error));
           } else {
             console.log('Conditional payment proposed {}', response);
             let paymentauth = response.data.paymentauth;
             resolve(response);
           }
         },
       );
     } catch (error) {
       console.log('Error {}', error);
       reject(new Error(error));
     }
 });
}

Note that at this moment, the G2C Suite uses an expiration deadline of 15 days in conditional proposal call; after that deadline, if the payee has not performed any action (either accept or reject), funds locked by this function call will be rolled back to the payer.

Accept conditional payment

Payee is allowed to accept the conditional payment before the deadline using g2cclient_walletConditionalAccept() G2C library function. Once accepted, the payment is automatically credited to the payee.

async conditionalPaymentAccept() {
   return new Promise((resolve, reject) => {
     try {
       // acceptParameters object contains the following fields:
       // const acceptParameters = {
       //    tokenid,
       //    tokens1,
       //    tokenc1,
       //    application,
       //    paymentauth,
       // }
       g2cclient_walletConditionalAccept( acceptParameters, (response) => {
           if (response.hasOwnProperty('error')) {
               console.log('Error {}', error);
               reject(new Error(response.error));
           } else {
             console.log('Conditional payment accepted {}', response);
             let acceptTxId = response.data.accepttxid;
             let costs = response.data.costs;
             resolve(response);
           }
         },
       );
     } catch (error) {
       console.log('Error {}', error);
       reject(new Error(error));
     }
  });
}

Reject conditional payment

In case payee does not want to accept the payment, it can call the g2cclient_walletConditionalReject() function from G2C library to reject it. Otherwise, g2cclient_walletConditionalAccept() must be called to rollback the operation.

async conditionalPaymentReject({ paymentauth, tokenc1, tokenid, tokens1 }) {
   return new Promise((resolve, reject) => {
     try {
       // rejectParameters object contains the following fields:
       // const rejectParameters = {
       //    tokenid,
       //    tokens1,
       //    tokenc1,
       //    application,
       //    paymentauth,
       //  }
       g2cclient_walletConditionalReject(rejectParameters, (response) => {
           if (response.hasOwnProperty('error')) {
               console.log('Error {}', error);
               reject(new Error(response.error));
           } else {
             console.log('Conditional payment rejected {}', response);
             let rejectTxId = response.data.rejecttxid;
             let costs = response.data.costs;
             resolve(response);
           }
         },
       );
     } catch (error) {
       console.log('Error {}', error);
       reject(new Error(error));
     }
  });
}