Integration Guide

πŸ“˜

Glossary

Partner - a company or platform that utilizes the crypto settlement API to manage cryptocurrency transactions. Partners integrate with Paybis to enable cryptocurrency functionalities within their systems, allowing to offer crypto-related services to their clients - Merchants.

Merchant - a business entity that operates with Partner, utilizing the Partner's services to handle cryptocurrency transactions. Merchants are responsible for initiating crypto payments to end-users (Users) via the infrastructure provided by the Partner.

User - the end recipient of cryptocurrency payouts. Users interact with Merchants’ platforms to receive crypto payments. They are the final beneficiaries in the cryptocurrency transaction process managed by the Partner and Merchant.

General Information

Business Process Flow

Use Case Description

  1. Partner validates the wallet address with Paybis API - Crypto Address Screening API.
  2. Partner gets a quote from Paybis - Quote API.
  3. Partner sends the payout request to Paybis - Execute API.
  4. Paybis accepts the requests and processes the crypto payout to the requested crypto address.
  5. Once the payout has been executed, Paybis notifies Partner of the status of the payout - Transaction Data Webhook.
  6. Paybis deducts the transaction amount from the Partner’s balance.

πŸ“˜

Settlements procedure is covered by legal agreement.

Environments

Sandbox

Paybis provides a sandbox environment for partners to use for testing the APIs quickly and easily. The Sandbox environment includes a few differences from the production one making it suitable for testing.

  • Please use sandbox API key, will be provided during onboarding.
  • Sandbox API URL will be provided during onboarding.
  • IP whitelisting is not enforced in Sandbox, in contrary to production.
  • Crypto payouts done using Testnet blockchain networks.

Production

  • Please use production API key, will be provided during onboarding.
  • Production API URL will be provided during onboarding.
  • IP whitelisting will be enforced in Production, to be shared with Paybis and enforced before go-live.

API Specification

Paybis provides REST API endpoints that accepts JSON as request body and responds with a JSON as output.

  • API_BASE_URL: will be provided during onboarding
  • PARTNER_WEBHOOK_URL: configurable per Partner
  • PARTNER_API_URL: configurable per Partner (used only for 5.4.1 Message Queue integration option)

πŸ“˜

Strings length

Default length of string properties is 255 characters (if other is not specified).

Authentication

Each request to Paybis API must include an API key in the Authorization HTTP header.

API key will be assigned and provided to the Partner during onboarding.

Signing requests

All requests to the server should be signed with the private RSA key using theRSASSA_PSS_SHA_512signing algorithm. Paybis uses the public key to verify signature and authenticity of your request.

There are two ways to generate the RSA key pair:

  • Recommended. Keys are generated by the partner, and the public key is provided to Paybis integration manager.
  • Keys are generated on Paybis end and the private key is passed to the Partner by the integration manager in a secure way.

🚧

If the private key was lost or compromised, you need to notify the integration team immediately: the related public key stored on the Paybis end should be revoked and the new key pair should be generated.

Generating RSA keys

If you prefer to generate the key pair on your end, you can use the following commands:

  1. Generate private 4096-bit RSA key.
openssl genrsa -out private.key 4096
  1. Create public key from the private key.
openssl rsa -in private.key -outform PEM -pubout -out public.pub
  1. Provide thepublic.pubkey to the Paybis integration manager.

Signing HTTP Requests

Signature should be generated from the private 4096 bit RSA key and HTTP request body hash using using theRSASSA_PSS_SHA_512asymmetric signing algorithm. After that, the signature is encoded with Base64.

Signature = Base64(RSASSA_PSS_SHA_512(PRIVATE_KEY, SHA512(requestBody)))

Signature should be passed in theX-Request-SignatureHTTP header.

If the request signature validation fails, 403 HTTP error code is returned.

Crypto Address Screening API

This optional endpoint allows the Partner to verify that the End-user’s entered crypto address is not problematic policy-wise. If Paybis rejects the address, End-user will have to enter a different crypto address.

Request direction

Partner β†’ Paybis

Request

POST <API_BASE_URL>/v1/user-screening

ParameterTypeDescription
crypto_currencyREQUIRED stringCrypto asset code (i.e. BTC, ETH).
wallet_addressREQUIRED stringCrypto asset wallet address for the payout.
{
  "crypto_currency": "BTC”,
  "wallet_address": β€œ13BgLTnJ9wfVgQePm9crVBfaxnTbPCqj61”
}

Response

ParameterTypeDescription
is_approvedbooleanTrue if the address passed screening, False if not.
reasonstringThe reason of address screening failure. Returned if only is_approved is False.
Status-Code: 200 OK
{
  "is_approved": false,
  "reason": "User's wallet address is invalid"
}

Quite API

Provides the possibility to create a quote based on either fiat or crypto amount.

Request direction

Partner β†’ Paybis

Request

POST <API_BASE_URL>/v1/quote

ParameterTypeDescription
quote_idREQUIRED uuidPartner generated identifier of a specific quote in UUID format.
crypto_currencyREQUIRED stringCrypto asset code.
fiat_currencyREQUIRED stringFiat currency code.
requested_currencyREQUIRED stringBase crypto or fiat currency for quote calculation, see request examples.
requested_amountREQUIRED stringRequested amount with precision 2 for fiat and 8 for crypto.

Paybis will provide a list of enabled crypto and fiat currency pairs configured per specific partner.

{
  "quote_id": "383b15d9-611f-4452-a973-00790ebc7835",
  "crypto_currency": "BTC",
  "fiat_currency": "USD",
  "requested_currency": "BTC",
  "requested_amount": "0.123456"
}
{
  "quote_id": "fee931bb-de84-448a-bf19-4d38f819925a",
  "crypto_currency": "BTC",
  "fiat_currency": "USD",
  "requested_currency": "USD",
  "requested_amount": "123.45"
}

Response

ParameterTypeDescription
quote_iduuidIdentifies a specific quote.
timedatetimeQuote creation timestamp.
expirationdatetimeQuote expiration timestamp.
digital_moneyobject
digital_money.currencystringDigital currency code.
digital_money.amountstringDigital currency amount.
fiat_moneyobject
fiat_money.currencystringFiat currency code.
fiat_money.amountstringFiat currency amount.
Status-Code: 201 Created
{
  "status": "ok",
  "result": {
    "quote_id": "383b15d9-611f-4452-a973-00790ebc7835",
    "digital_money": {
      "currency": "BTC",
      "amount": "1.03"
    },
    "fiat_money": {
      "currency": "USD",
      "amount": "5304.29"
    },
    "time": "2023-09-16T11:10:00"
    "expiration": "2023-09-16T11:20:00"
  }
}

Execute API

There are two options to pass the crypto payout request to Paybis:

  1. Using API endpoint (recommended option).
  2. Using Message Queue.

Partner can implement any one of the options or even both of them simultaneously to improve resiliency.

Partners that choose to use the Message Queue option will need to implement two API endpoints on their backend:

  1. List Events
  2. Delete Event

Execute - API Endpoint

The Execute API is idempotent, therefore requests can be safely retried as long as the Event ID does not change between requests for the same crypto payout.

Care must be taken to handle error responses and retry the request until a successful response from Paybis is received.

Request direction

Partner β†’ Paybis

Request

POST <API_BASE_URL>/v1/event

ParameterTypeDescription
event_idREQUIRED uuidUnique event identifier in UUID format.
Paybis will use this ID as an idempotency key.
nameREQUIRED stringEvent name.
Must be constantpayment_execute.
timestampREQUIRED datetimeRequest timestamp.
paymentREQUIRED object
payment.transactionREQUIRED objectTransaction details.
payment.transaction.idREQUIRED uuidPayment transaction identifier generated by Partner, i.e. specific payout id
payment.transaction.order_idREQUIRED uuidOrder identifier generated by Partner, i.e. mass payout id
payment.transaction.quote_idREQUIRED uuidReferenced quote id.
Must be a valid and not expired quote.
payment.transaction.fiatREQUIRED object
payment.transaction.fiat.currencyREQUIRED stringFiat currency of the transaction.
Must match the quote fiat currency.
payment.transaction.fiat.amountREQUIRED stringFiat amount of the transaction.
Must match the quote fiat amount.
payment.transaction.cryptoREQUIRED object
payment.transaction.crypto.currencyREQUIRED stringCrypto currency of the transaction.
Must match the quote crypto currency.
payment.transaction.crypto.amountREQUIRED stringCrypto amount of the transaction.
Must match the quote crypto amount.
payment.transaction.merchantREQUIRED stringCrypto transaction sender.
Must be a string up to 16 characters in length.
payment.crypto_destination.typeREQUIRED stringDestination crypto address type.
Must be constantuser.
payment.crypto_destination.crypto_addressREQUIRED stringDestination crypto wallet address.
payment.crypto_destination.userREQUIRED objectCrypto transaction beneficiary details.
payment.crypto_destination.user.user_idREQUIRED stringReceiver name.
Must be a alphanumeric string w/o spaces. Max length: 70 characters.
{
  "event_id": "0000079f-6981-4cd7-bf7b-88c5699eebb5",
  "name": "payment_execute",
  "payment": {
    "transaction": {
      "id": "26e312b9-2206-1005-227e-f95808946cd3",
      "order_id": "7e67bcad-36b9-757e-eddf-96c904228cb9",
      "quote_id": "32b5d20c-e281-41e4-9035-1263ed8eeb04",
      "fiat": {
        "amount": "13853.96",
        "currency": "USD"
      },
      "crypto": {
        "amount": "0.31488388",
        "currency": "BTC"
      },
      "merchant": "sender-name"
    },
    "crypto_destination": {
      "type": "user",
      "crypto_address": "1CoYiGR7S7CiWn75bTYpFMTr6n5SxX8zZz",
      "user": {
        "user_id": "receiver-name"
      }
    }
  },
  "timestamp": "2023-09-16T18:07:55.769Z"
}

Response

{
    "status": "ok",
    "result": {
        "event_id": "87e2d429-529b-4542-b366-704d1e591750",
        "name": "payment_execute",
        "payment": {
            "transaction": {
                "id": "6f0f0b4d-de82-428b-a298-a4a06392f175",
                "order_id": "7b3e9d21-54a3-403a-bc06-00627df2976f",
                "quote_id": "850c535d-5d58-4b6f-86ee-c0614c86ff45",
                "fiat": {
                    "amount": "7.10",
                    "currency": "USD"
                },
                "crypto": {
                    "amount": "7.000000",
                    "currency": "USDT-TRC20"
                },
                "merchant": "advertiser-name"
            },
            "crypto_destination": {
                "type": "user",
                "crypto_address": "TXJApRfPs1BbwDdYGT9AVQkZg8UeFuwgoy",
                "user": {
                    "user_id": "getrid-oldauth"
                }
            }
        },
        "timestamp": "2023-09-16T18:07:55+00:00"
    }
}

List Events - Message Queue

Partner implements a message queue on their side and Paybis will poll Partner’s API periodically to retrieve new requests.

In general, a message in queue will contain the Event ID (UUID), the Event name (payment_execute) and the Event details.

πŸ“˜

For your information

  • quote expiration time can be set based on agreement between Paybis and Partner, default is 10 minutes.
  • if execution event will refer an expired quote, event will not be executed and will be deleted from Message Queue
  • It’s expected that Partner will manage such case on their side, if quote has expired then new quote to be requested and new event to be submitted to Message Queue with a new valid quote.

Request direction

Partner β†’ Paybis

Request

GET <PARTNER_API_URL>/events

No input parameters.

Response

The response from Partner should contain a list of all outstanding events that were not yet processed and subsequently deleted from the Message Queue.

ParameterTypeDescription
event_idREQUIRED uuidUnique event identifier in UUID format.
Paybis will use this ID as an idempotency key.
nameREQUIRED stringEvent name.
Must be constantpayment_execute.
timestampREQUIRED datetimeRequest timestamp.
paymentREQUIRED object
payment.transactionREQUIRED objectTransaction details.
payment.transaction.idREQUIRED uuidPayment transaction identifier generated by Partner, i.e. specific payout id
payment.transaction.order_idREQUIRED uuidOrder identifier generated by Partner, i.e. mass payout id
payment.transaction.quote_idREQUIRED uuidReferenced quote id.
Must be a valid and not expired quote.
payment.transaction.fiatREQUIRED object
payment.transaction.fiat.currencyREQUIRED stringFiat currency of the transaction.
Must match the quote fiat currency.
payment.transaction.fiat.amountREQUIRED stringFiat amount of the transaction.
Must match the quote fiat amount.
payment.transaction.cryptoREQUIRED object
payment.transaction.crypto.currencyREQUIRED stringCrypto currency of the transaction.
Must match the quote crypto currency.
payment.transaction.crypto.amountREQUIRED stringCrypto amount of the transaction.
Must match the quote crypto amount.
payment.transaction.merchantREQUIRED stringCrypto transaction sender.
Must be a string up to 16 characters in length.
payment.crypto_destination.typeREQUIRED stringDestination crypto address type.
Must be constantuser.
payment.crypto_destination.crypto_addressREQUIRED stringDestination crypto wallet address.
payment.crypto_destination.userREQUIRED objectCrypto transaction beneficiary details.
payment.crypto_destination.user.user_idREQUIRED stringReceiver name.
Must be a alphanumeric string w/o spaces. Max length: 70 characters.
[
  {
    "event_id": "0000079f-6981-4cd7-bf7b-88c5699eebb5",
    "name": "payment_execute",
    "payment": {
      "transaction": {
        "id": "26e312b9-2206-1005-227e-f95808946cd3",
        "order_id": "7e67bcad-36b9-757e-eddf-96c904228cb9",
        "quote_id": "32b5d20c-e281-41e4-9035-1263ed8eeb04",
        "fiat": {
          "amount": "13853.96",
          "currency": "USD"
        },
        "crypto": {
          "amount": "0.31488388",
          "currency": "BTC"
        },
        "merchant": "advertiser-name"
      },
      "crypto_destination": {
        "type": "user",
        "crypto_address": "1CoYiGR7S7CiWn75bTYpFMTr6n5SxX8zZz",
        "user": {
          "user_id": "publisher-name"
        }
      }
    },
    "timestamp": "2023-09-16T18:07:55.769Z"
  }
]

Delete Event - Message Queue

Once the event has been taken care of by Paybis, Paybis will issue the Delete Event request. Partner should remove the referenced event from the Message Queue.

Request direction

Partner β†’ Paybis

Request

DELETE <PARTNER_API_URL>/events/:event_id

ParameterTypeDescription
event_idREQUIRED uuidEvent id.

Response

A 2xx successful response is expected, otherwise Paybis will retry the request.

Transaction Data Webhook

Webhook on successfully executed event, after crypto transaction is submitted to the blockchain.

Request direction

Paybis β†’ Partner

Request

POST <PARTNER_WEBHOOK_URL>

ParameterTypeDescription
event_idREQUIRED uuidEvent id.
transaction_idREQUIRED uuidTransaction id.
Paybis will return value from payment.transaction.id from the corresponding Event.
digital_amount_sentREQUIRED object
digital_amount_sent.currencyREQUIRED stringCrypto currency sent to the crypto address.
digital_amount_sent.amountREQUIRED stringCrypto amount sent to the crypto address.
blockchain_txn_hashOPTIONAL stringThe blockchain transaction hash.
{
  "event_id": "0000079f-6981-4cd7-bf7b-88c5699eebb5",
  "transaction_id": "26e312b9-2206-1005-227e-f95808946cd3",
  "digital_amount_sent": {
    "currency": "BTC",
    "amount": "0.699999"
  },
  "blockchain_txn_hash": "492e43fa04ec86d7d4bc7deb38e4956312e78eb68d97824e73660a52283344ab"
}

Response

A successful HTTP response is expected (2xx code).

If Paybis receives any other status code in the response, the webhook request will be retried for up to 24 hours with exponential backoff.