PSP / Wire Transfers (with verification)
Add money via Visa\MasterCard bank cards (with verification)
Put the payment button on a merchant web-site. When you or your customer clicks on this button, data is sent to the address of the GarryPay system.
info
To provide security, whole sended data must have been crypto signed.
The workflow consists of two steps. Step one - open an account and KYC procedure. Second step - make payment.
A customer must go via KYC procedure only one time. After confirming a customer documents, not need go to KYC procedure once again. To confirm this, a merchant should provide GarryPay id of this customer on a website. The customer id connects with the exact merchant only. This why, in next transactions on a merchant website, the KYC for same customer under the same ID will not need.
The KYC page and the payment page are called via the one same request. The KYC page will shown if a customer with a specified ID has not confirmed his documents before. The payment page will shown, if a document of a customer with the same ID was already confirmed.
Preparation and auxiliary actions
- Create a wallet in USDT TRC20 crypto currency
- If you would like to be informed about the sum of fiat currency in a transaction,create a wallet in EUR currency please.
- Create a merchant and attach a wallets above to them.
Restrictions
danger
We do not accept payments from list of the countries: (list and text with restrictions must be placed on well viewed place a merchant website)
List of countries
- Burundi
- Central African Republic
- Cuba
- Crimea
- Iran
- Iraq
- Lebanon
- Libya
- North Korea
- Somalia
- South Sudan
- Darfur (Sudan)
- Syria
- Venezuela
- Yemen
- Albania
- Belarus
- Bosnia and Herzegovina
- Bulgaria
- Democratic Republic of the Congo
- Croatia
- Kosovo
- Macedonia
- Montenegro
- Romania
- Serbia
- Slovenia
- Zimbabwe
- USA
- Turkmenistan
- Israel
- Canada
- Russia
Integration via payment button
The payment button code should looks the same like:
<form action="https://merch-dev.garrypay.com/basis_payment" method="post">
<input
type="hidden"
name="data"
value="eyJvcmRlcl9pZCI6IjIyIiwiYW1vdW50IjoiMTAiLCJjdXJyZW5jeSI6IlVTRFQiLCJ1c2VyX2lkIjoiMSIsIm1lcmNoYW50X2lkIjoiMTc0YTNjYjMtYTBlMC00NDUzLThmYTctNTdhMDE2OGM3ZGY3Iiwic2VjcmV0S2V5IjoiZDNkNmViMDBiYTQ0MDcxZmFmMmJlZGU4OWNhMTM4MjRjYWE4MTkwOTc4MjJkOTBiZGJmNGY1NzZjMTI1M2VlNTk2YmQ0NDgzMzJhZTYwYjY2ZDc4In0"
>
<input
type="hidden"
name="sign"
value="C1/DssOPem7ChcKUDsKYOjhLwq/DqMK3bDscDjYcwrI9wqhAwojCl8K4wrkNIQ=="
>
<input class="btn" type="submit" value="Send">
</form>
Info for the data field is preparing by following (a code example):
Base64.encode('{
"merchant_id": "ef73bed1-2591-4a91-a74e-fe68b4e2e4e0",
"lang": "en",
"order_id": "1eas123",
"user_id": "122",
"amount": "100.32",
"currency": "EUR"
}');
Thus the JSON object must translate in string and encode in Base64.
Permissed fields
Name | Type | Default | Description |
---|---|---|---|
merchant_id | string | Required | Your merchant ID |
order_id | string | Required | Unique order ID |
user_id | string | Required | Unique user ID (you can use email) |
string | Required | Email of the user, who makes the payment | |
amount | string | Required | Amount in described currency |
currency | string | Required | Currency used for payment |
lang | string | en | Payment interface language, en / ru |
callback | string | undefined | URL a page, that see a customer after success payment |
type | string | Required | Payment type
|
Code example
- JS
- PHP
import crypto from "crypto";
const data = new Buffer(JSON.stringify({
merchant_id: "xxx"
order_id: "234-12",
amount: "102.5",
currency: "EUR",
user_id: "123",
type: "1",
})).toString("base64")
const hmac = crypto.createHmac("sha256", key);
hmac.update(data);
const sign = Buffer.from(hmac.digest("hex")).toString("base64");
$params = [
'merchant_id' => 'xxx',
'order_id' => '234-12',
'user_id' => $user->id,
'email' => $user->email,
'amount' => 102.5,
'currency' => 'EUR',
'lang' => $lang,
'type' => 1,
'callback' => 'https://merchant_site.com/callback_url',
];
$data = base64_encode(json_encode($params));
$sign = base64_encode(hash_hmac('sha256', $data, $secret));
Callback
Server IP address, from which requests are received: 185.49.70.96
info
The payment process is divided into two stages
The user passes verification
The user makes a payment
Since we cannot guarantee that the user at the verification stage will specify the same email that you sent in the request, in the sandbox we emulate the situation that the user specified a different email. We pass it upon successful verification at step psp_kyc_step3
In order to proceed to the second stage and debug the payment callbacks, replace the email in your request with the one you receive in the callback at the psp_kyc_step3 stage from the user_email
parameter
Request example
{
data: 'eyJhY3Rpb24iOiJwMnBfcHJkZXIiLCJkYXRhIjp7ImRhdGEiOnsiYWRfaWQiOjUyMSwiYW1vdW50IjoxMDAsImN1cnJlbmN5IjoiVVNEIiwibWVyY2hhbnRfaWQiOiI5MGYxZDE5OC05MjkzLTQwNjItYjc5NC05NDgxNmM3NWNjODYiLCJjb3VudHJ5IjoicnVzIn0sImVycm9yIjoiTUVSQ0hBTlRBQ0NPVU5UTk9URk9VTkQifX0=',
sign: 'MGM4NGIyZTY2OWMyNzYzNjFhODcyODdjZGViN2UxMWQ4MzY2ZmNiYmE4ZDRiOTVhMTU1ODMxYTZlYTMwYjJmZg=='
}
data - JSON encoded in base64
sign - data signature
Data authentication
- Generate a signature using base64 encoded received data and your Secret Key
- Verify the generated signature with the one received from the request.
- If the signature matches, the data is authentic, they can be decoded and processed further
Sign generation based on the received data:
- JS
- PHP
//secret Key - Your merchant's secret key
const hmac = crypto.createHmac("sha256", secretKey);
//base64data - Encoded data from the request
hmac.update(base64data);
const sign = Buffer.from(hmac.digest("hex")).toString("base64");
//$secretKey - Your merchant's secret key
//$base64data - Encoded data from the request
$sign = base64_encode(hash_hmac('sha256', $base64data), $secretKey));
Operation stages
Each callback in the data object contains the action
parameter. Thanks to this parameter, it is possible to determine at what stage the verification / payment process is.
KYC:
Action | Description |
---|---|
psp_kyc_step1 | The user has started the KYC process |
psp_kyc_step2 | The user submitted the KYC form |
psp_kyc_step3 | Verification passed |
Examples of KYC callbacks
psp_kyc_step1
{
"action":"psp_kyc_step1",
"data": {
"email":"tst_10@test.com",
"user_id":"tst_10"
}
}
psp_kyc_step2
{
"action":"psp_kyc_step2",
"data": {
"basis_user_hash":"10_1653901265246",
"merchant_id":"xxx",
"user_id":"tst_10",
"email":"tst_10@test.com",
"ip":"::ffff:127.0.0.1",
"bstatus":0
}
}
psp_kyc_step3
{
"action":"psp_kyc_step3",
"data":{
"basis_hash_id":"10_1653901741508",
"basis_user_id":"1653901741513",
"email":"1653901741513@test.com",
"merchant_id":"xxx",
"user_id":"tst_10",
"user_email":"1653901741513@test.com",
"first_name":"Maxx",
"last_name":"Xamm",
"middle_name":"",
"phone":"",
"phone2":"",
"bstatus":10,
"profile":{
"access_token":"aat-79874831-39b7-4e00-bb4e-980799cad464",
"address":"Lenina, 12",
"address2":"",
"autocheck_bad_reasons":"video",
"birthday":"2000-11-11",
"city":"Kandagar",
"country":"AF",
"country_name":"Afghanistan",
"country_residence":"AF",
"country_residence_name":"Afghanistan",
"document_number":"",
"email":"1653901741513@test.com",
"email_confirmed":"true",
"expiry_date":"0001-01-01",
"first_name":"Maxx",
"gender":"male",
"id":"2129803",
"issue_date":"0001-01-01",
"last_name":"Xamm",
"middle_name":"",
"passport":"\/passport\/83230a4a-2829-463a-8536-968617eb67eb.jpg",
"passport2":"",
"phone":"",
"phone2":"",
"photo":"\/video\/a61f4f38-2feb-4ae4-8205-751ab883146f.mp4",
"photo_image":"",
"user_hash":"67175f61-29d9-4205-9690-f7e1537f3b54",
"utility_bill":"\/bill\/7f6bb828-4cfe-4a0f-96db-ba474c10c236.jpeg",
"zip":"123444"
}
}
}
Payment callbacks:
Action | Description |
---|---|
psp_paymentlink_requested | The payment link has been requested and will be sent to the email of the user who pays (for amounts that are not prepared links) |
psp_paymentlink_sent | The user is directed to the payment form |
psp_prepayment | Payment received from the user |
psp_payment_completed | The payment of cryptocurrency to the merchant has been made, the transaction is completed |
psp_cancel | The user clicked the cancel payment button |
Examples of payment callbacks
psp_paymentlink_requested
{
"action":"psp_paymentlink_requested",
"data":{
"order_id":"461",
"user_id":"tst_10",
"email":"1653901741513@test.com",
"merchant_id":"xxx",
"amount":10,
"currency":"EUR",
}
}
psp_paymentlink_sent
{
"action":"psp_paymentlink_sent",
"data":{
"amount":10,
"currency":"EUR"
}
}
psp_prepayment
{
"action":"psp_prepayment",
"data":{
"order_id":"463",
"user_id":"tst_15",
"email":"tst_15@test.com",
"amount":10,
"currency":"EUR",
}
}
psp_payment_completed
{
"action":"psp_payment_completed",
"data":{
"order_id":"463",
"user_id":"tst_15",
"email":"tst_15@test.com",
"merchant_id":"xxx",
"amount":10,
"currency":"EUR",
"lang":"en",
"type":"1",
"callback_url":"https:\/\/test.com\/send-me-callback",
"ip":"::ffff:127.0.0.1"
}
}
psp_cancel
{
"action":"psp_cancel",
"data":{
"order_id":"444",
"user_id":"tst_10",
"email":"1653668006688@test.com",
"merchant_id":"xxx",
"amount":10,
"currency":"EUR",
"lang":"en",
"type":"1",
"callback_url":"https:\/\/test.com\/send-me-callback"
}
}
Callbacks are sent by sending an HTTP POST request to the address specified in merchant settings.
Attention!
During testing, you will not see the payment form. The user's payment process is emulated, and you receive payment callbacks, as it would be if the user paid through the payment form.
Inform your client to specify the same email address when paying as during verification, in order to avoid loss of payment