- Intro
- Dependencies
- Get started
- Merchant SDK API Reference
- sdk.build
- sdk.executePullPayment
- sdk.monitorRegistrationTransaction
- sdk.monitorCancellationTransaction
- Class sdk.Scheduler
- sdk.Scheduler.start
- sdk.Scheduler.restart
- sdk.Scheduler.stop
- sdk.generateQRCode
- sdk.generateEthPushQRCode
- sdk.generateErc20PushQRCode
- sdk.fundETH
- sdk.cashOutETH
- sdk.cashOutPMA
- sdk.validateSecretPhrase
- sdk.encryptData
Decentralized vision has developed a payment protocol that allows recurring payment to occur over the Ethereum Blockchain. This SDK module provides the core functionality to any third party integrator to allow execution of PullPayments.
More details regarding the PumaPay PullPayment Protocol and the PumaPay ecosystem can be found in our wiki
The merchant SDK needs to communicate with PostgreSQL database (referenced as Pull Payment DB from now on) which stores the billing models, the PullPayments and the Ethereum transactions.
More details in our wiki
MySQL database is an encrypted database used for encrypting the HD wallet with the Ethereum addresses that the merchant uses on their end for executing PullPayments on the blockchain, for funding the PullPayment account addresses with ETH to pay for gas and cashing out PMA and ETH to a treasury account on their end.
Check our wiki for more details on the HD Wallet and the treasury account.
Redis in-memory data structure store is used for storing information related to the PullPayment account address that will be executing the PullPayment and for storing the maximum gas used for a PullPayment transaction.
First you need to get merchant_sdk to your project through npm
npm install @pumapay/merchant_sdk --save
Import sdk from npm
import merchant_sdk from '@pumapay/merchant_sdk';
Instantiate the sdk
const sdk = new merchant_sdk();
Recommended to be used as a singleton. Example:
class MerchantSDK {
private static sdk: merchant_sdk = null;
private constructor() {}
/**
* @description Returns the instantiated sdk object
*/
public static GET_SDK() {
if (this.sdk) {
return this.sdk;
}
this.sdk = new merchant_sdk();
return this.sdk;
}
}
Construct the sdk with the required parameters
const settings: SDKBuildSettings = {
web3: web3Provider, // web3 provider for ethereum network
merchantApiUrl: https://merchant_example_url.com/, // merchant backend url
pgUser: db_user, // PostgreSQL db user
pgHost: db_host, // PostgreSQL db host
pgPort: db_port, // PostgreSQL db port
pgDatabase: db_name, // PostgreSQL db name
pgPassword: db_password, // PostgreSQL db password
redisClient: redis_client // Redis client e.g. redis.createClient(redis_port, redis_host)
getEnums: enumerables, // method for getting enumerables
getPullPayment: getPullPaymentCallback, // callback for getting payment from DB
updatePullPayment: updatePullPaymentCallback, // callback for updating payment from DB
getTransactions: getTransactionsByPullPaymentCallback, // callback for getting transactions from DB
createTransaction: createTransactionCallback, // callback for creating transactions from DB
updateTransaction: updateTransactionCallback, // callback for updating transactions from DB
getPrivateKey: getPrivateKey // callback for getting private key based on hd wallet address
bankAddress: getBankAddress // callback for getting ethereum address to be used as a bank address from the HD wallet
}
See below for detailed explanation.
Build the sdk using provided parameters.
sdk.GET_SDK().build(settings);
NOTE: The merchant SDK is encapsulated in a NodeJS server which will be referred to as Merchant Core Server from now on.
sdk.build(settings)
The build method is used to build the SDK.
Parameters
SdkSettings
- Settings to initiate the merchant sdk
Returns
object
- The merchant SDK or error
if provided settings are incorrect
Example
sdk.build({
web3: web3Provider, // web3 provider for ethereum network
merchantApiUrl: https://merchant_example_url.com/, // merchant core server url
pgUser: db_user, // PostgreSQL db user
pgHost: db_host, // PostgreSQL db host
pgPort: db_port, // PostgreSQL db port
pgDatabase: db_name, // PostgreSQL db name
pgPassword: db_password, // PostgreSQL db password
redisClient: redis_client // Redis client e.g. redis.createClient(redis_port, redis_host)
getEnums: enumerables, // method for getting enumerables
getPullPayment: getPullPaymentCallback, // callback for getting PullPayment by ID from DB
updatePullPayment: updatePullPaymentCallback, // callback for updating a PullPayment in DB
getTransactions: getTransactionsByPullPaymentCallback, // callback for getting transactions for a specific PullPayment from DB
createTransaction: createTransactionCallback, // callback for creating transactions from DB
updateTransaction: updateTransactionCallback, // callback for updating transactions from DB
getPrivateKey: getPrivateKey // callback for getting private key based on hd wallet address
bankAddress: getBankAddress // callback for getting ethereum address to be used as a bank address from the HD wallet
})
Callbacks:
- getPullPayment(paymentID)
Parameters
string
- pull payment ID
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
id: '2400005a-0000-0000-0000-f28000009fd1',
...
}
]
}
Example
await getPullPayment('2400005a-0000-0000-0000-f28000009fd1')
- updatePullPayment(updateDetails)
Parameters
object
- Payment update details
{
id: string;
hdWalletIndex: number;
numberOfPayments: number;
nextPaymentDate: number;
lastPaymentDate: number;
startTimestamp: number;
merchantAddress: string;
statusID: number;
userID: string;
networkID: number;
}
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
id: '2400005a-0000-0000-0000-f28000009fd1',
...
}
]
}
Example
await updatePullPayment({...})
- getTransactions(transactionDetails)
Parameters
object
- Transaction details
{
paymentID: string;
statusID: number;
typeID: number;
}
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
id: '2400005a-0000-0000-0000-f28000009fd1',
...
}
]
}
Example
await getTransactions({...})
- createTransaction(transactionDetails)
Parameters
object
- Transaction details
{
hash: string;
paymentID: string;
statusID: number;
typeID: number;
}
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
id: '2400005a-0000-0000-0000-f28000009fd1',
...
}
]
}
Example
await createTransaction({...})
- updateTransaction(transactionDetails)
Parameters
object
- Transaction details
{
statusID: number;
typeID: number;
}
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
id: '2400005a-0000-0000-0000-f28000009fd1',
...
}
]
}
Example
await updateTransaction({...})
- getPrivateKey(address)
Parameters
string
- Address of the wallet which is executing pull payment
Returns
Promise - {
success: true //boolean
status: 200 //integer
message: '' //string
data: [
{
@accountKey: 'private_key',
}
]
}
Example
await getPrivateKey('0x3ae8205c4258888ee976e05a8ed50645e0100000')
- getBankAddress()
Returns
Promise - {
bankAddress: '0x8574205c4258888ee976e05a8ed50645e0100000'
}
Example
await getBankAddress()
sdk.executePullPayment(pullPaymentID)
Executes a PullPayment stored in the DB on the Ethereum network.
For the execution of the PullPayment, the PullPayment needs to be retrieved from the Pull Payment DB which contains details about the wallet address that can execute the PullPayment.
The blockchain transaction is signed by the wallet address linked with the PullPayment and is transmitted to the Ethereum network.
Once the transaction hash is obtained by the Ethereum network a new blockchain transaction with the txHash
linked to the PullPayment is inserted in the Pull Payment DB with status pending
.
If the transaction receipt is retrieved from the blockchain with status true
the status in the db changes to success
otherwise is set to failed
.
Parameters
string
- PullPayment ID that needs to be executed on Ethereum blockchain
Returns
undefined
Example
sdk.executePullPayment('2400005a-0000-0000-0000-f28000009fd1')
sdk.monitorRegistrationTransaction(txHash, pullPaymentID)
Monitors a PullPayment registration transaction on the blockchain.
The PullPayment registration is submitted to the Ethereum network by the PumaPay Core after the PullPayment was signed in the PumaPay Wallet.
Once the transaction receipt is retrieved in the PumaPay core, it is sent to the PumaPay Merchant server and stored in the Pull Payment DB as a registration transaction for the specified pullPaymentID
with status pending
.
The blockchain transaction is monitored on the merchant side and updated once the blockchain transaction receipt is retrieved.
If the transaction receipt is retrieved from the blockchain with status true
the status in the db changes to success
otherwise is set to failed
.
Parameters
string
- txHash of the registration transaction as retrieved by the blockchainpullPaymentID
- PullPayment ID that was registered on Ethereum blockchain
Returns
Promise<object>
- Blockchain transaction receipt or error
if monitoring failed
Example
sdk.monitorRegistrationTransaction('0xaeed582d5a8165f9130e15b10a480400126b67fb21402623258626774c000000', '2400005a-0000-0000-0000-f28000009fd1')
sdk.monitorCancellationTransaction(txHash, pullPaymentID)
Monitors a PullPayment cancellation transaction on the blockchain.
The PullPayment cancellation is submitted to the Ethereum network by the PumaPay Core after the PullPayment was signed in the PumaPay Wallet.
Once the transaction receipt is retrieved in the PumaPay core, it is sent to the PumaPay Merchant server and stored in the Pull Payment DB as a registration transaction for the specified pullPaymentID
with status pending
.
The blockchain transaction is monitored on the merchant side and updated once the blockchain transaction receipt is retrieved.
If the transaction receipt is retrieved from the blockchain with status true
the status in the db changes to success
otherwise is set to failed
.
Parameters
string
- txHash of the cancellation transaction as retrieved by the blockchainpullPaymentID
- PullPayment ID that was cancelled on Ethereum blockchain
Returns
Promise<object>
- Blockchain transaction receipt or error
if monitoring failed
Example
sdk.monitorCancellationTransaction('0xaeed582d5a8165f9130e15b10a480400126b67fb21402623258626774c000000', '2400005a-0000-0000-0000-f28000009fd1')
new sdk.Scheduler(pullPaymentID, callback)
The Scheduler class is starting / stopping / restarting the scheduler which is executing a PullPayment.
Parameters
string
- PullPayment ID that needs to be executed on Ethereum blockchainfunction
- callback function
Returns
undefined
Example
new sdk.Scheduler('2400005a-0000-0000-0000-f28000009fd1', sdk.executePullPayment)
new sdk.Scheduler(pullPaymentID, callback).start(reinitialized? = false)
Starts the scheduler based on a PullPayment ID and a callback.
The scheduler is used for executing a PullPayment on the blockchain i.e. pull PMA from the customer account. This function is being called on sdk.monitorRegistrationTransaction
and when the transaction receipt is successful, the scheduler starts with sdk.executePullPayment(pullPaymentID)
as the callback function.
Parameters
boolean
- (optional) whether the scheduler should be re-initialized
Returns
undefined
Example
sdk.Scheduler('2400005a-0000-0000-0000-f28000009fd1', sdk.executePullPayment).start()
sdk.Scheduler.restart(pullPaymentID)
Restarts the scheduler based on a PullPayment ID. The scheduler can be restarted only if it is stopped.
Parameters
string
- PullPayment ID
Returns
undefined
Example
sdk.Scheduler.restart('2400005a-0000-0000-0000-f28000009fd1')
sdk.Scheduler.stop(pullPaymentID)
Stops a running scheduler based on a PullPayment ID.
Parameters
string
- PullPayment ID
Returns
undefined
Example
sdk.Scheduler.stop('2400005a-0000-0000-0000-f28000009fd1')
sdk.generateQRCode(paymentModelID)
This function is being used to generate the QR code object. It can be called after a new pull payment model is created by passing as a parameter the ID of the model.
Parameters
string
- ID of the pull payment model for which you want to generate QR code
Returns
{
pullPaymentModelURL: `https://merchant_example_url.com/payment-model/${paymentModelID}`,
pullPaymentURL: `https://merchant_example_url.com/payment/`,
transactionURL: `https://merchant_example_url.com/transaction/`
}
Example
sdk.generateQRCode('2400005a-0000-0000-0000-f28000009fd1')
sdk.generateEthPushQRCode(address, value, gas)
This function is being used to generate the QR code object for Ethereum push transaction.
Parameters
string
- Address of the Ethereum wallet that is to receive ethers sentstring
- Big number value of the amount to be transferedinteger
- Transaction gas limit that is to be used
Returns
{
to: `${address}`,
value: `${value}`,
gas: `${gas}`,
data: null
}
Example
sdk.generateEthPushQRCode('0x3ae8205c4258888ee976e05a8ed50645e0100000', '10000000000', 21000)
sdk.generateErc20PushQRCode(tokenAddress, address, value, gas)
This asynchronous function is being used to generate the QR code object for any ERC20 push transaction. Address of the token contract needs to be provided. Transfer method for ERC20Basic tokens is encoded using address and value and passed in the data payload.
Parameters
string
- Address of the token contractstring
- Address of the Ethereum wallet that is to receive tokensstring
- Big number value of the amount to be transferedinteger
- Transaction gas limit that is to be used
Returns
{
to: `${tokenAddress}`,
value: `0x00`,
gas: `${gas}`,
data: '0xa9059cbb000000000000000000000000c5b42db793cb60b4ff9e4c1bd0c2c633af90acfb000000000000000000000000000000000000000000000000000000000000000a'
}
Example
sdk.generateErc20PushQRCode('0x5a48205c6258888ee976e05a8ed50645e0111111', '0x3ae8205c4258888ee976e05a8ed50645e0100000', '10000000000', 21000)
sdk.fundETH(fromAddress, toAddress, pullPaymentID, value? = null, tokenAddress? = null, pullPaymentAddress? = null)
This function is being used to transfer ETH from one address to another one. It is called when a new PullPayment is registered to transfer ETH from the treasury account to the executor account that will be used for gas throughout the lifecycle of a PullPayment.
Parameters
string
- from which address to transfer the ETHstring
- to which address to transfer the ETHstring
- PullPayment ID related with this fundingnumber
- (optional) value of ETH to be transferred - if not provided will be calculatedstring
- (optional) token address of the PMA token that is used for calculating the gas fee for transferring PMA - if the value is not providedstring
- (optional) PullPayment address that is used for calculating the gas fee for transferring PMA - if the value is not provided
Example
sdk.fundETH('0x3ae8205c4258888ee976e05a8ed50645e0100000', '0x3ae8205c4258888ee976e05a8ed50645e0111111', '2400005a-0000-0000-0000-f28000009fd1')
sdk.cashOutETH(pullPaymentID, tokenAddress? = null)
This function is being used to cashing out ETH for a PullPayment based on the ID one address to another one. The cash-out of ETH happens at the end of the PullPayment lifecycle so that all the remaining ETH that were not used for gas are transferred back to the treasury account.
Parameters
string
- PullPayment IDstring
- (optional) token address of the PMA token that is used for calculating the gas fee for transferring ETH - if the value is not provided
Example
sdk.cashOutETH('2400005a-0000-0000-0000-f28000009fd1')
sdk.cashOutPMA(pullPaymentID, tokenAddress?= null, forceCashOut? = false)
This function is being used to cashing out PMA for a PullPayment based on the ID one address to another one.
The automated cash-out of PMA is specified on the creation of the PullPayment model by the merchant by setting automatedCashOut
to true
along with the
cashOutFrequency
which represents the number of executions after which an automated cashout will take place.
Parameters
string
- PullPayment IDstring
- (optional) token address of the PMA token that is used for calculating the gas fee for transferring ETH - if the value is not providedboolean
- (optional) defaultfalse
- iftrue
the cashout will be executed without checking thecashOutFrequency
Example
sdk.cashOutPMA('2400005a-0000-0000-0000-f28000009fd1')
sdk.validateSecretPhrase(encryptedPhrase)
This function is being used to authenticate wallet requests. Wallet app sends in the header a phrase which is encrypted with the private key safely secured on the wallet app. This method decrypts the encrypted phrase with corresponding public key and compares it with the phrase value on the SDK.
Parameters
string
- encryptedPhrase that, when decrypted, matches the phrase on the SDK
Returns
- true - if the encryptedPhrase is valid
- false - if the encryptedPhrase is corrupted
Example
sdk.validateSecretPhrase(`${encryptedPhrase}`)
sdk.encryptData(data)
This function is being used to encrypt data that needs to be sent to the wallet app. Data is encrypted using the public key so that only the wallet (which has the private key) can decrypt it.
Parameters
object
- data JSON parameters to be encrypted
Returns
- string - if the encryption is successfull
- null - if the encryption failed
Example
sdk.encryptData({data: 'string'})