Ecommerce Payments Using PHP/Javascript
Overview
Online shopping continues to grow everyday with new point of sale (POS) and shopping cart solutions being developed. Central to every shopping cart is a payment system that allow merchants to collect payments from clients. Blockchain infrastructure is working to decentralize payment systems by eliminating geographical barriers for for everyone. Therefore, solutions like this will allows merchants to collect real-time payments and have instant liquidity as well instead of waiting 2 to 3 days for settlement. Blockchian systems need to interface with traditional online shopping carts to reduce payment friction faced by both buyers and merchants alike.
Introduction
The Algorand-blockchain-payment project is a PHP/Javascript implementation of an ecommerce payment module on a custom PHP shopping cart. It allows the user to pay for goods and services using the Algorand blockchain cryptocurrencies and stablecoins. Users will have to sign the transactions before payment is successful and the transaction is recorded on the blockchain with the payment details embedded within the Algorand blockchain transaction note field.
Dependencies
This implementation uses the Algorand Javascript SDK which you can download from GitHub or install if you have NPM installed. Here is a quick start guide.
To get the cryptocurrency rates to USD or any other currencies, the Binance API is used to pull the rates.
You will also need a database and web server running PHP. We use Xammp for this purpose.
Interacting with Algorand chain
There are three ways of sending and retrieving transactions on Algorand. First option is to install and run an Algorand Node locally to process the transactions (highest technical knowledge). Second, use Sandbox to spin up a node quickly (medium technical knowledge). Third, is to use a third-party API Service Provider to interact with the blockchain (lowest technical knowledge).
This solutions uses the third-party APIs because they offer simple endpoints to post and retrieve transactions on the chain without requiring you to run a local node. While some offerings are free, others require fees after certain transactions limits. There are currently two options namely, Purestake API Service (requires an account to get API keys) and AlgoExplorer Developer API which requires no account signup. We combine using both service providers for different purposes but if you don’t want to create an account with Pure Stake, just stick with AlgoExplorer API.
TestNet vs MainNet
We use the TestNet for all testing but you could just switch the API endpoints in either Pure Stake or AlgoExplorer to use the MainNet when you are ready. It is really that simple.
Deployment
This is a PHP implementation which will run on any Linux server that supports PHP. This implementation was done on a Xampp localhost. To deploy and test this…
- Simply upload the folder into the
htdocs
folder or run it in your public_html folder on a shared hosting, for example. Run the index.php script to start the script. The index.php is the storefront which loads the products from the database. It allows the user to add products to cart, which are stored in the browser session. The user can edit the cart before proceeding to checkout - You will need to created the databases using the
tblproducts.sql
. You can run this script/ dump it to create the tables for you. We have pre-populated it with sample products to test with. Change the following to your database details
private $host = "localhost";
private $user = "root";
private $password = "password";
private $database = "algopay";
- The folder includes the Algosdk as and example but you should import this using NPM or always make sure you link to the latest version
- In the js/scrips.js file, set the address to receive payments. The Mnemonic keys of this address will be used to sign transactions as well. See the explanations in the code below.
- In checkout.php, this is where the Algorand payment transaction processing happens. You can edit as much as you want. This file is where the user initiates the payments. The check file converts the product price to the selected Algorand payment asset. Once the user is happy with the price conversion, they will supply their mnemonic phrase to sign the transaction. It displays a success message after payments and redirects the user a thank you page supplied by the merchant.
Backend merchant settings
The merchant who is going to receive payments needs to set their address, Mnemonic keys, and the types of Algorand assets to accept as payment. This solution only supports ALGO but we added other dummy tokens to see how it works. From the Github Repo, the file scrips.js in the js folder is where these configurations are done.
/* Conversion Price Configs
* Change the value of the contant below to your preferred price option
* [lastPrice / bidPrice / askPrice / openPrice / highPrice / lowPrice]
* Also replace the merchAlgoAddress with a valid Algorand Address
*/
const convPrice = "bidPrice";
const merchAlgoAddress = "HIPB2IEVJ43VG66VFGBMIWNBHPIPXI6EDIOFNB3BN2E2KHWNPYSE8EORKAE";
const merchCallbackURL = "./?"; // Replace this with your preferred callback URL and add '?' at the end
const authTimeOutMils = 300000; //in mili-Seconds
const authTimeOutSecs = 30; //in Seconds
var cardDrop = document.getElementById('card-dropdown');
var activeDropdown;
cardDrop.addEventListener('click',function(){
var node;
for (var i = 0; i < this.childNodes.length-1; i++)
node = this.childNodes[i];
if (node.className === 'dropdown-select') {
node.classList.add('visible');
activeDropdown = node;
};
})
window.onclick = function(e) {
if (e.target.tagName === 'LI' && activeDropdown){
if (e.target.innerHTML === 'USDC') {
activeDropdown.classList.remove('visible');
activeDropdown = null;
e.target.innerHTML = document.getElementById('current-card').innerHTML;
document.getElementById('current-card').innerHTML = 'USDC';
document.getElementById('cryptSymbol').value = 'BTCUSDT';
convertBill();
}
else if (e.target.innerHTML === 'Planets') {
activeDropdown.classList.remove('visible');
activeDropdown = null;
e.target.innerHTML = document.getElementById('current-card').innerHTML;
document.getElementById('current-card').innerHTML = 'OKEx';
document.getElementById('cryptSymbol').value = 'Planets';
convertBill();
}
else if (e.target.innerHTML === 'ALGO') {
activeDropdown.classList.remove('visible');
activeDropdown = null;
e.target.innerHTML = document.getElementById('current-card').innerHTML;
document.getElementById('current-card').innerHTML = 'ALGO';
document.getElementById('cryptSymbol').value = 'ALGOUSDT';
convertBill();
}
}
else if (e.target.className !== 'dropdown-btn' && activeDropdown) {
activeDropdown.classList.remove('visible');
activeDropdown = null;
}
}
function genRandomID(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
Explaing Checkout.php
This file is a combination of PHP and Javascript. You will need to include the database class to perform some CRUD (Create, Read, Update, Delete) actions. This part of the implementation picks session data of items added to cart and calculates the total price, total quantity, creates a random orderID and makes assisnges these as variables. It then converts the total price to ALGOS using the binance API (but you could use AlgoExplorer API for this).
You will need a valide Purestake API KEY. The one here is a dummy one
Part 1: The first part of the checkout is the PHP/Html component that displays the frontend below
Next is the JS code on the checkout.php to process payment. It does the following
1. Takes the user’s address and mnemonic keys at the storefront to deduct the payment
You will need to update this section with your PurStake API details
if(cAddress===jsonRes[0].address){
//const algosdk = require('algosdk');
const baseServer = "https://testnet-algorand.api.purestake.io/ps2"// change to https://algorand.api.purestake.io/ps2 if you are on the mainnet
const port = "";
const token = {
'X-API-key' : 'Put your PureStake API key',
}
- Creates the payload using cart values to sign transaction to the Algorand chain when the transaction is complete
- The buyer’s name and other details are formated and added as a note in the transaction.
window.onload = function() {
//cryptSymbol = 'ALGOUSDT';
const orderID = genRandomID(7);
<?php if(isset($_SESSION["cart_item"])){ ?>
$("#order-id").val(orderID);
$("#order-info-title").html('#'+orderID+' | Order Summary');
<?php } ?>
showLoader();
convertBill();
};
$("#main").html('<center><img src="./success-anim-1.gif" style="width: 100%; height: 100%; object-fit: cover;display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex;"></center>').delay(800).fadeOut(1000, function() {
location.replace(merchCallbackURL+"oxID="+oxID+"&txID="+txID);
});
$(this).remove();
});
}
}
Note
This is meant to be a guide for PHP developers to understand blockchain interactions. Using a framework and OOP approach was considered too advanced for a beginner. Any experienced developer should be able to abstract this for a higher level implementation.
Contributions welcome to the Algorand-blockchain-payment project repo on GitHub.
A more secure approach
For a live production, it is advisable to integrate with AlgoSigner browser extension. This will allow the customer securely sign transactions with exposing their mnemonic password.
Conclusion
The solution allows merchants to set up a storefront and accept payments using Algorand Standard Assets. The user on the other hand can securely pay for the goods/services using his/her Algorand mnemonic keys. The user details are sent as a note in the Algorand payments.