How to charge with PumaPay on your site
The alpha version of the PumaPay SDK is now available for developers and businesses to use free of charge. Built around the features of the ERC20 token, this initial version of the PumaPay solution is an open-source protocol that flexibly integrates with any kind of merchant platform. This allows developers to either clone the entire project or use only parts of it directly into their platform or edit it as it may suit the merchant's needs. While this only facilitates a crypto-typical push action, the full-scale Pull protocol will come with a future version of this software.
This first version of our SDK can be found on our GitHub account and consists of a user interface (UI) through which people can buy photos using PumaPay Tokens (PMA) and the back-end server, which consists of a set of APIs that can be used to allow for the customers to make purchases using either the PumaPay wallet mobile application or Metamask. A PostgreSQL database is attached to the back-end server to deal with authentication, purchases and basic e-commerce business logic.!
The main programming language that we’ve used for the development of the different components is Typescript. Specifically, we’ve used NodeJS written in TS for our backend and Angular 5 for our frontend.
Before diving into more technical details, let us first explore the application, what it does and how someone can use it to purchase photos (or any other kind of product). Feel free to check our live demo.
Our PumaPay demo boutique allows us to demonstrate the concept of purchasing photos using PumaPay Tokens without the need to register (unregistered purchase). We will refer to the photos as items from hereafter since our solution is generic.
It illustrates the concept of purchasing credit packages that can be used for buying the items (credit purchase).
For additional details please refer to our previous article.
PumaPay Payment Flow
The payment flow using PumaPay Tokens is very simple and straightforward, and it supports both registered and unregistered user’s purchases. The customers can select an item (unregistered purchase) or a credit package (credit purchase) that they would like to purchase using PumaPay. On the item/credit package selection a session is being initiated in our backend and stored in our database for future reference of the specific purchase. The session ID is also stored in the local storage of the client. The customer is then presented with the option to purchase using either our PumaPay Mobile Wallet or Metamask.
We will stick to the unregistered purchase scenario in the rest of the article, even though there are no differences between registered and unregistered use case when it comes to the payment flow. The only difference is that in the latter case, the customer purchases item, whereas in the former one, credits that the customer can use for purchases.
PumaPay Mobile Wallet Payment
When the user decides to pay using the PumaPay Mobile Wallet, a QR is being generated using the session ID and the item ID to construct a URL linked to one of our APIs. That API constructs the transaction details and presents it to the mobile wallet for the customer to approve the payment and submit the transaction to the blockchain. At that point, a web socket is established for that specific session, which communicates the transaction statuses (scanned, open, approved, declined, cancelled) to the client. Once the transaction is approved by the blockchain network, the customer has completed the purchase.
Metamask Payment
We have integrated our transactions via the Metamask chrome plugin, this allows us to verify and carry out transactions through the plugin. The integration with Metamask is very similar with the wallet payment flow, with the only difference being that instead of calling the API to retrieve the transaction details data from the wallet, an API is being called from the client to retrieve the same data, and initiates the transaction through the Metamask plugin.
Technical Deep Dive | Code Samples
In this section the most important parts of our SDK will be explained in more detail with code samples. You can find the full list of our APIs here.
Backend | Node.js – Typescript
Session Creation
Once the customer selects an item to purchase, a session is created in our backend, which is stored in our database and sent back to the client to be used as a reference for the purchase session that has been initiated.
interface ISession {
sessionID: string;
txHash: string;
status: TxStatus;
fromPumaWallet: boolean;
}
enum TxStatus { initiated = -1, scanned, open, approved, declined, cancelled }
Transaction Data Creation
When the customer selects the payment option (PumaPay wallet or Metamask) a request is being sent in our backend, which constructs the transaction data for that specific purchase. The session ID is being sent along with the item ID. The item details (_name, _description, _value) are retrieved from our DB with the owner ETH address (_to) to build the transaction data through our Transaction Builder.
class Transaction {
private _hash: string;
private _callback: string;
private _description: string;
private _name: string;
private _networkID: number;
private _to: string;
private _value: number;
private _signature: string;
public constructor(transactionBuilder: TransactionBuilder) {
this._callback = transactionBuilder.callbackUrl;
this._description = transactionBuilder.description;
this._name = transactionBuilder.name;
this._networkID = 3;
this._to = transactionBuilder.to;
this._value = unit.convert(transactionBuilder.value, 'eth', 'wei');
this._signature = new SignatureCalculator(this).calculate();
}
}
Transaction Data Signing
The transaction data includes the signature of the transaction itself, which serves as a verification mechanism from the mobile wallet to specify whether a transaction comes from a secure and verified merchant. The hash is being calculated using solidity Keccak256 function with a prefixed message, which is eventually being signed with a private key. On the wallet side, the signature is being decrypted and the public key is checked against a list of verified sources.
public calculate(): string {
// convert the transaction data into a hex hash using keccak256
const hash = Buffer.from(ethers.utils.solidityKeccak256(
['bytes', 'bytes', 'bytes', 'uint256', 'address', 'uint256'],
[
//the variables of type bytes need to be converted in utf8
Buffer.from(this.transaction.callback, 'utf8'),
Buffer.from(this.transaction.description, 'utf8'),
Buffer.from(this.transaction.name, 'utf8'),
this.transaction.networkID,
this.transaction.to,
this.transaction.value
]).substr(2), 'hex');
// store in a buffer the message as a prefix variable
const prefix = new Buffer('\x19Ethereum Signed Message:\n');
// store in a buffer the hash and then convert the hash with the prefix into a new hex hash using keccak256
const prefixedMsg = Buffer.from(
ethers.utils.keccak256(Buffer.concat(
[prefix, new Buffer(String(hash.length)), hash]
)).substr(2), 'hex');
const privateKey = Buffer.from(PRIVATE_KEY_OF_MERCHANT, 'hex');
// convert the prefix message and the private key using ecsign to create the digital signature
const sig = utils.ecsign(prefixedMsg, privateKey);
// convert the signature parameters r,v,s into the format of eth signature RPC method using toRpcSig
return utils.toRpcSig(sig.v, sig.r, sig.s);
}
Callback URL
The callback URL is used for updating the transaction status from the blockchain network. Query parameters for the transaction hash, the status and a boolean are attached to it to update the session in the DB. It is called from the mobile wallet or the client when the transaction is being scanned, submitted, approved, declined or cancelled.
transactionBuilder.callbackUrl =
`${HOST}${PREFIX}transaction/item/txStatus/session/${sessionID}`;
Web Socket
When the callback URL is being called either from the wallet app or the client, a web socket is created for that specific session, which transmits the updated session details (see above) to the client.
webSocket.emit(`txStatus/${sessionID}`, sessionDetails);
Frontend | Angular 5 – Typescript
Session Handling
A new session is initiated from the client every time that the customer selects an item to purchase (photo/credit package). Once the session ID is retrieved from the backend, it is stored in the local storage of the browser from where it is retrieved later to generate the QR code, establish the web socket connect and retrieve the transaction status for the specific session. When the customer decides to select another product for purchase, the local storage of the browser is cleared, and the new session ID is stored. This is a very simplistic way of dealing with sessions, and it is suggested that the merchant should use their existing session handling.
QR Code Generator
The QR generator lives within our client, which essentially constructs the URL to one of our APIs to retrieve the transaction data for the initiated session and the selected item for purchase.
public getQrDataForItem(): string {
const sessionID = localStorage.getItem('sessionID');
const itemID = localStorage.getItem('itemID');
return JSON.stringify(
{
url: `${HOST}${PREFIX}transaction/item/tx/plain/${sessionID}/${itemID}`});
}
Web Socket
The connection with web socket initiated in the backend is established from the client once the customer selects to pay with either our PumaPay wallet or the Metamask plugin. The session ID from the local storage is being used to connect to the correct web socket connection. Once there is a new status coming from the backend, the status on the UI is also being updated to let the customer know the status of their transaction, at any point.
Conclusions
We have designed and implemented a unique push payment protocol and demo boutique that both demonstrates and gives implementers the ability to make purchases in a quick and efficient manner.
Thanks to technology today through software applications and programming languages we can make our world a faster and more versatile world, thanks for sharing @pumapay
Great project
The alpha version of the PumaPay SDK is now available for developers & businesses to use free of charge. Lets disrupt the traditional payment system with advanced pull payment technology of PumaPay.
It is really great to see the payment system on website that accept payment in cryptocurrency. BTW, what will be your charge for connecting users to the business owners in term of payments. Do you have any plan to add your system with the websites like amazon, ebay or flipkart. If you can do it.. you will be very huge in the near future. I am a fan of PumaPay and holding you coins. Your answer will be appreciated. Thanks!
Hi, thanks so much for your question. We are a free and open source protocol, therefore we will not be charging users. However, we are interested in partnering with many well known and established businesses in the future.
What about tokensale?
Token Sale has been concluded in early may only with historical contribution of $117M+. If you want PMA token you can participate in bounty campaign https://bitcointalk.org/index.php?topic=3809188.0.
PumaPay is surely destined to be a big hit among many merchants and ordinary guys like you and me...keep it up and always be ahead in the competitive game.
Wow! Pumapay will definitely help a lot and might revolutionize the way transactions are made.
good project and big opportunity