Integrating PiratePay into your website with custom code.
- Table of Contents:
- Introduction - Coding for the PiratePay Payment Gateway Application
- Initiating a Transaction with the PiratePay Application.
- How does PiratePay find a transaction once initiated?
- Checking the Status of a Transaction on the PiratePay Application.
- Final thoughts and a note on increasing efficiency with Modules.
Introduction - Coding for the PiratePay Payment Gateway Application.
In this guide we will be discussing how to integrate PiratePay into your Store, Website or Platform using code customized to fit your individual needs. This guide is designed to be used in conjunction with your PiratePay’s API documentation located at your PiratePay Applications URL path: /documentation.
Please note: You will also need PiratePay setup and running to begin communicating with your PiratePay Applications API.
Initiating a Transaction with the PiratePay Application.
To initiate a transaction with PiratePay you will need to make a HTTP POST request to your PiratePay’s URL path: /api/v1/initiate. With this API call you will be required to pass a few details about your stores order, including an order identifier, currency and price. Some examples of required values include:
- Authorization: Bearer {token} Inside your POST Header you will be require to pass the OAuth API Key that you generated inside your PiratePay dashboard at URL path: /dashboard/api_token. This API key is used to authenticate your access to the PiratePay Application.
- store_order_id: This is an identifier that your website or store uses to identify the individual transaction. Typically an Order Number, or an Order ID. (This can be used by your code/website to locate a transaction status during your API callback.)
- store_currency: This parameter is used to pass the FIAT currency abbreviation to PiratePay to help it understand which currency to convert the ARRR against, example values: USD, EUR, GBP, AUD.
- store_order_price: This parameter is used to pass the FIAT grand total cost/value of an order, including taxes and shipping (If required), it should not contain any symbols, it should be formatted in English Notation without a thousands separator, while using a period as a decimal point separator between the dollar and cents value instead of a comma commonly used in some European countries. (Examples: 1.00 1000.00 100000.00)
- store_buyer_name: This parameter is used to pass the Customers Name, PiratePay uses this to help the Store Administrator identify which person a transaction belongs to if needed for customer support.
- store_buyer_email: Similarly to buyer name above, the buyer email is used mainly to assist in identifying who a transaction came from inside the PiratePay dashboard, making it easier to quickly contact said customer if needed.
Example HTTP POST request to /api/v1/initiate wrote in PHP:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://mywebsite.com/api/v1/initiate',
[
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer {token}',
],
'json' => [
'store_order_id' => '5',
'store_order_price' => '1.00',
'store_currency' => 'USD',
'store_buyer_name' => 'John Doe',
'store_buyer_email' => '[email protected]',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
Once the above details have been successfully received by the PiratePay Application, it will return a JSON response containing the ARRR payment information, this information can be used to display payment details to the customer so they can begin the process of making payment.
Here is an example of the JSON Response that will be returned:
{
"data": {
"id": 10,
"store_order_id": "5",
"store_order_price": "1.00",
"store_currency": "USD",
"store_buyer_name": "John Doe",
"store_buyer_email": "[email protected]",
"crypto_address": "zs1kmzcd8h22l8u38hnfdqfxegr0ml0nav9wfqcqpj3wapk8gury6gqlg4xf7gz4kakc4cfwq74xjl",
"crypto_market_price": "0.088339",
"crypto_price": "0.226401",
"start_balance": "0",
"crypto_qr": "https://chart.googleapis.com\/chart?chs=300x300&chld=L|2&cht=qr&chl=pirate:zs1kmzcd8h22l8u38hnfdqfxegr0ml0nav9wfqcqpj3wapk8gury6gqlg4xf7gz4kakc4cfwq74xjl?amount=0.226401&message=16&label=16",
"created_at": "2020-11-26 11:36:06",
"updated_at": "2020-11-26 14:37:27"
}
}
Of note, PiratePay will return a duplicate of all the information sent to it. This is done in case you want to display any of the information back to the customer, save it in your database, or validate any of it to ensure the correct information was passed and received. In addition, you will also receive:
- id: This identifier is PiratePay’s own record of a transaction, it is numerical and incremented with every transaction recorded. No two transactions can share the same PiratePay ID. (This can also be used by your code/website to locate a transaction status during your API callback.)
- crypto_address: This is a new private address that PiratePay generated inside the Pirate Chain Wallet, this is the ARRR address that the customer will be making payment to.
- crypto_market_price: This value is used as a record of the current Market Price/Exchange Rate of ARRR at the time the transaction was initiated. You are welcome to display this to the customer so they can verify our FIAT -> ARRR conversions themselves if they have any concerns.
- crypto_price: This is the converted value of ARRR required to complete the transaction/order. For instance if your website passed the value of 5.00 USD, and the current usd value of each ARRR was $0.20, the customer would need to pay 25 ARRR, therefore crypto_price would return the value of “25.000000”.
- crypto_qr: This is a QR code image that was generated to display to your customer, it will allow them to pay using a supported mobile wallet. The QR code contains the wallet address, amount of ARRR required, and a label with an order number for ease of record keeping in their Wallet. You can display this image by putting it into simple html < img > tags, and passing the crypto_qr response into the src attribute.
Once received, all of these values can then be displayed to your customer allowing them to begin the payment process.
How does PiratePay find a transaction once initiated?
Once a transaction has been initiated using the above information, PiratePay will begin making periodic checks on the wallet address to verify if a transaction has been received in the ARRR wallet.
You can monitor the status of these transaction checks by going into the PiratePay dashboard and clicking on the Queue button at the top. Inside the Queue Monitor you can view the status of all recent wallet checks located inside the Pending, Completed, or Failed jobs tabs.
By default PiratePay will check the wallet for the needed transaction every 5 minutes, for up to 3 hours. If required this can be adjusted in the .env file by changing the WALLET_SCAN_MINUTES and WALLET_SCAN_MAX_ATTEMPTS variables (Example: 5 Minutes x 60 Attempts = Five Hours)
Please Note: if the .env file is changed the queue manager or server and wallet will need to be restarted to reflect these updates, in some cases PiratePay’s cache will also need to be cleared using the following commands:
cd/var/www/PiratePay
php artisan cache:clear
php artisan config:clear
Checking the Status of a Transaction on the PiratePay Application.
You can remotely check the status of a transaction by using the PiratePay Status API. To do this, simply make a HTTP POST request to your PiratePay URL path: /api/v1/status. Within this POST request you will need to include the Authorization header, and the following two parameters:
- Authorization: Bearer {token} Inside your POST Header you will be required to pass the OAuth API Key that you generated inside your PiratePay dashboard at URL path: /dashboard/api_token. This API key is used to authenticate your access to the PiratePay Application.
- type: (Options: “store_id”, or “id”) This parameter is used to tell PiratePay how you would like it to search for your transaction. You will typically use the “store_id” value. This means that PiratePay will find the transaction record based on the “store_order_id” you initially passed in the above Initiate API Call. Alternatively you can pass the value “id” and this will allow you to find a transaction based on PiratePay’s own numerical identifier. Using PiratePay’s ID can be useful if your store/website doesn’t generate or save its own Order Numbers, or in cases where duplicate order numbers may be an issue. The PiratePay ID is returned as “id” in every initiate API call made to PiratePay.
- id: Once you select the type parameter above, this will be the order id value you are searching for, for instance if the order you are trying to find is order number 115, you will input the value 115 into the id field.
Example HTTP POST request to /api/v1/status wrote in PHP:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'http://mywebsite.com/api/v1/status',
[
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer {token}',
],
'json' => [
'type' => 'store_id',
'id' => '2563',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
Once these values are passed, PiratePay will search for the transaction record, and the status of said transaction inside the PiratePay database. If found, you will receive a JSON Response similar to the record below.
Here is an example of the JSON Response that will be returned:
{
"data": {
"id": 1,
"store_order_id": "2563",
"store_order_price": "0.02",
"store_currency": "USD",
"store_buyer_name": "John Doe",
"store_buyer_email": "[email protected]",
"crypto_address": "zs1yu96c2uz8g0k04qcprj2ssg2rmkuvzgfa2ug8u0rrrysmh2sjzwksx780j78n9qwu9v0ynnjhqk",
"crypto_market_price": "0.097645",
"crypto_price": "0.204824",
"start_balance": "0",
"expected_balance": "0.204824",
"end_balance": null,
"status_detailed": "pending",
"status_basic": "false",
"created_at": "2021-01-04 18:21:17",
"updated_at": "2020-01-04 18:21:17"
}
}
Please Note: Before you use these details to mark a payment as received, it is recommended that you always validate against the store_currency and store_order_price fields. This is to ensure that in the rare chance an attacker gains access to your PiratePay API credentials, they will not be able to make PiratePay believe that a transaction price was less than expected for an order, or that it was made in a currency not intended by the store. Preventing them from making PiratePay believe that a $25 order was actually only a $1 order. By ensuring that PiratePay and your Website’s Order details match on the callback, you can protect yourself from an attack of this kind from happening.
Of note in this JSON Response, are the following status parameters:
- status_detailed: This parameter is used to give a detailed explanation of the current status of a transaction. For instance: pending, found, missing, overpaid, underpaid, and unknown. You can validate against all these values to process an order based on which one is received.
- status_basic: This parameter works similar to above, but instead of returning a detailed explanation, it returns a simple true or false value. It returns "true” to a “found” or “overpaid” status, and a “false” to a pending, missing, underpaid or unknown status.
For simple code where you only need to know if a customer paid at least enough to fulfill the order, you can validate against the “status_basic” parameter, otherwise if you would like more specific details you would validate against all the “status_detailed” parameter values.
Here is a list and the meaning of each status_detailed response:
- pending: This indicates that PiratePay has successfully initiated the transaction process, and is periodically checking the Wallet Address for the funds to arrive. (Returns a status_basic value of: false).
- found: This indicates that PiratePay has received the funds, and they appear to match all transaction parameters within a 95% accuracy. (Returns a status_basic value of: true).
- missing: This value indicates that PiratePay has completed the maximum number of transaction checks, but was not able to find any payment from the customer. This can be considered a payment not received. (Returns a status_basic value of: false).
- overpaid: This value indicates that the customer has overpaid/exceeded the ARRR value requested. This generally happens if the customer overpays by more than 5%. Typically you would consider this value as “paid” on your website, but it is a useful tool if you want/need to keep record of overpayments. (Returns a status_basic value of: true)
- underpaid: Similarly to above, this value indicates if a customer has underpaid the ARRR value requested. This generally happens if the customer underpays for an order by more than 5%. In these cases PiratePay will still continue watching for more transactions to come into that wallet totaling or exceeding the requested ARRR value. (Returns a status_basic value of: false)
- unknown: is a fallback value and typically only happens if there was some sort of error preventing PiratePay from completing all of its Wallet Checks. Typically when you see this value you should check the Queue Monitor for Failed jobs, or check your PiratePay error logs for additional details as to why the status is unknown. (Returns a status_basic value of: false)
Once you have all these transaction status details at your disposal, you can use it in your code to do several things, such as mark a payment as received, record the transaction details on your website, finalize a transaction, notify the customer the payment was completed, provide a receipt, etc.
Final thoughts and a note on increasing efficiency with Modules.
With all of the information provided above, you should be able to communicate with PiratePay’s API to initiate an ARRR transaction, as well as track the status of said transaction from your website or store.
Worth noting: PiratePay does have some other nifty features to handle status updates. For instance it is possible to create a module inside PiratePay itself that will send status responses directly to your store or websites API, eliminating the need for your store to have to repeatedly make callbacks to PiratePay asking for status updates on a transaction. These modules can be a useful tool to increase efficiency, and to further take processing load off of your websites servers. However due to the high complexity involved with inversely communicating with other platforms API’s, we will not be able to cover how to create custom modules within this article.
If you have any questions about PiratePay, or any of our services, please feel free to message us below.