TripleA Bitcoin Payments API (1.0.0)

Download OpenAPI specification:Download

Introduction

Welcome to TripleA! Our documentation provides everything you need to start accepting Bitcoin payments.

With Bitcoin payments, there’s no sensitive customer information to collect and store, and there are no cards to charge. Customers simply send funds (Bitcoin) from their computer or mobile device directly to a (unique one-time-use) payment address. TripleA monitors the blockchain and provides real-time payment updates. Updates can be shared by email, dashboard or API calls to your own backend.

You can accept bitcoin payments in a variety of ways.

  1. External URL payment form.
    Pay via URL redirection, which will lead to our hosted payment solution with our payment form.
  1. Embedded payment form.
    Pay within your site with the embedded payment form.
  1. Content Management System (CMS) plugins.
    Instant setup for your WooCommerce or OpenCart CMS.

  2. Custom Integration.


Simplifying Bitcoin Payments

At TripleA we have tried our best to simplify the process of taking Bitcoin as a payment method.

Real time conversion

When a Bitcoin payment is initiated, we guarantee the exchange rate for 25 minutes. Once the funds arrive, the Bitcoin will be instantly converted to local currency at the guaranteed exchange rate.

TripleA takes the bitcoin exchange rates from several authoritative sources, such as Kraken
and Coinbase.

Funds that arrive after 25 minutes will be considered on a case by case basis.

Instant Confirmation

Once a Bitcoin payment is broadcasted to the Bitcoin network, TripleA will make a decision in a few seconds on whether the payment is good. If we determine a payment is good, the merchant will be guaranteed to receive the funds no matter what happens to the transaction thereafter.

Short Payment Topup

If buyers scan and pay using our QRCode, then we correct amount will be send everytime. However, sometimes buyers may be using other wallets or entering in amounts directly into their wallet. If they make a mistake and are short by a few cents, we will automatically top up to the requested amount and absorb that liability.

This is to enhance the merchant's and buyers' experience, as we know it is expensive for top up just a few cents in Bitcoin.

Authentication and Credentials

Making a payment request is an authenticated API call. We use OAuth2 Client Credentials grant. OAuth2 is an open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.

payment_auth

TripleA uses the OAuth2 Client Credentials grant. To get a token, click here.

Security Scheme Type OAuth2
clientCredentials OAuth Flow
Token URL: https://api.triple-a.io/api/v1/oauth/token
Scopes:

    bearer_auth

    Merchants who make any request to the API need to insert the token in the Authorization header.

      Authorization : Bearer <access_token>
    
    Security Scheme Type HTTP
    HTTP Authorization Scheme bearer
    Bearer format "access_token"

    If you have not received your credentials, sign up on our website and you will receive an email with the credentials.

    You will receive Dashboard Login (a username and a password) and API credentials.

    The API credentials come in a form of :

      Client ID: oacid-*****************
      Client Secret: ********************************************
      Live API ID : HA**************************
      Sandbox API ID : HA**************************_t

    Client ID and Client Secret are used for the authorization in getting the access token, which is needed for API call.

    Live API ID is an identifier for a merchant to accept a single cryptocurrency.

    Sandbox API ID is an identifier for a merchant to accept a testnet cryptocurrency (eg. testnetBTC). These testnet BTC are worthless and are used only for testing if the payment system works.


    Reset Credentials

    For any reason, you can request to have your Client Secret reset. However, this will invalidate ALL outstanding access tokens. Please contact support@triple-a.io if you want to reset your Client Secret.

    Payments

    External URL Payment Form

    Overview

    One of the simplest ways to integrate with TripleA is using the External URL Payment Form, which basically is a URL redirection to Triple-A hosted payment page.

    Here is a flow diagram to illustrate the process :


    Payments Flow


    Before you get started

    • Get your TripleA credentials and merchant accounts .
    • Generate an oauth token.

    Integration Steps

    Based on the above diagram, below are the steps:

    1. Make a payment request

    You can start by making a payment request. For this method, please ensure you use 'type' : 'triplea' in the request body parameters. You may also supply your webhook url as notify_url and a notify_secret (for verification of the incoming webhook data) in the request body.

    A sucessful JSON response from the payment request would look like this :

      {
        "payment_reference": "AQH-100306-PMT",
        "crypto_currency": "testBTC",
        "crypto_address": "mhdJd37khi21VgeWcjMKM9BVxYj29tHvAt",
        "crypto_amount": 0.00080051,
        "order_currency": "USD",
        "order_amount": 5.29,
        "exchange_rate": 6608.33,
        "expiry_date": "2020-04-22T08:52:11.842Z",
        "access_token": "736511b84cdd67cfb0ecdf555828276aaddc26dc",
        "token_type": "Bearer",
        "expires_in": 3599,
        "hosted_url": "https://triple-a.io/app/v1/payment_form?payment_reference=AQH-100306-PMT&access_token=736511b84cdd67cfb0ecdf555828276aaddc26dd"
      }

    2. Redirect user to payment form

    You will need to redirect the user to our external URL payment form, by using the hosted_url received from the response.


    3. Wait for user payment

    Users will see the payment form with the necessary information of payment details.

    Normal Payment Form


    4. Payment notification

    When users have made a payment, you will receive the payment notification via email and/or webhook integration. This notification will be POSTed back to the notify_url that you have specified in the payment request.

    If there was no URL specified, it will default to the notification URL provided when the merchant was set up.

    In rare cases where a user overpaid by a considerable amount, refunds are possible.

    Embedded Payment Form

    Overview

    If you would like to have the payment form embedded in your site , without redirect to our external URL payment form, we provide the Embedded Payment Form method.

    Here is a flow diagram to illustrate the process :


    Payments Flow


    Before you get started

    • Get your TripleA credentials and merchant accounts .
    • Generate an oauth token.

    HTML Integration Steps

    Based on the above diagram, here are the steps:

    1. Request a payment form

    You can start by making a payment request. For this method, please ensure you use 'type' : 'widget' in the request body parameters. You may also supply your webhook url as notify_url and a notify_secret (for verification of the incoming webhook data) in the request body.

    A sucessful JSON response from the payment request would look like this :

      {
        "payment_reference": "AQH-100306-PMT",
        "crypto_currency": "testBTC",
        "crypto_address": "mhdJd37khi21VgeWcjMKM9BVxYj29tHvAt",
        "crypto_amount": 0.00080051,
        "order_currency": "USD",
        "order_amount": 5.29,
        "exchange_rate": 6608.33,
        "expiry_date": "2020-04-22T08:52:11.842Z",
        "access_token": "736511b84cdd67cfb0ecdf555828276aaddc26dd",
        "token_type": "Bearer",
        "expires_in": 3599,
        "hosted_url": "https://cdn.triple-a.io/widgets/triplea-ecommerce-payment-v1.1/?payment_reference=AQH-100306-PMT&access_token=736511b84cdd67cfb0ecdf555828276aaddc26dd"
      }

    2. Embed and update the payment form code

    Insert the below HTML code into your front-end template where you wish the payment form to appear. Use the payment_reference and access_token properties from the above JSON response to update the attribute values for the payment form.

      <triplea-ecommerce-payment-v1
        payment-reference=”<PAYMENT_REFERENCE_HERE>”
        access-token=”<ACCESS_TOKEN_HERE>”
      >
      </triplea-ecommerce-payment-v1>
      <script src="https://cdn.triple-a.io/widgets/triplea-ecommerce-payment-v1.1/js/app.js"></script>

    On page load, the payment form will be displayed. The user can proceed with payment.


    3. Payment notification

    When users have made a payment, you will receive the payment notification via email and/or webhook integration. This notification will be POSTed back to the notify_url that you have specified in the payment request.

    If you did not specify a notify_url, it will default to the notification URL provided when the merchant was set up. If this one is empty as well, an update notification will only be sent by email and not to your server.

    In the rare case where a user overpays by a considerable amount, a refund can be made.

    Iframe Integration Steps


    Configure the iframe

    This follows the same steps as for the above HTML Integration Steps.

    When using an iframe to display the payment form, use the below src URL in which you replace payment_reference and access_token values:

    <iframe 
      id="triplea-payment-form"
      src="https://cdn.triple-a.io/widgets/triplea-ecommerce-payment-v1.1/?payment_reference=<VALUE>&access_token=<VALUE>"
      style="width:500px; height: 700px; border: 0;"
      scrolling="no"
    >
    </iframe>

    The payment form is responsive and adjusts to the width you assign it. Width and height in the above example are just suggestions to get you started.


    Message Events

    The payment form uses the postMessage browserAPI to notify your parent window of relevant events happening to it. You can easily listen to and handle these events within your own site.

    Example code :

    (function(){
      window.addEventListener('message', e => {
        console.log('message received', e.data);
      }, false);
    })();

    These are events the payment form currently posts :

    • triplea.frameResized|<height> - When the payment form size changes. Example :
      • Payment form loads.
      • Payment form or user collection form is displayed.
      • Payment form is expired.
      • Cart details are open or closed.
    • triplea.formExpired - When the payment form timer is expired or payment reference & access token are invalid.
    • triplea.paymentTooLittle - When the payment is not made in full.
    • triplea.paymentSuccess - When the payment has been made.

    If you are using iframe, you can easily adjust the iframe's height when its contents change to avoid scrollbars (if desired) :

    (function(){
      window.addEventListener('message', e => {
        console.debug('message received:', e.data);
        let iframe = document.getElementById("triplea-payment-form");
        if(typeof e.data === 'string' && e.data.indexOf("|") > 0){
          const res = e.data.split("|");
          if(iframe && res[0] === 'triplea.frameResized'){
            iframe.style.height = res[1] + 'px';
          }
        }
      }, false);
    })();

    Some of the scenario examples where the messages are expected to fire :

    Scenario : User makes full payment.

    1. Payment form loads -> triplea.frameResized|<height> event occurs.
    2. If user opens cart details -> triplea.frameResized|<height> event occurs.
    3. User makes payment in full amount -> triplea.paymentSuccess and triplea.frameResized|<height> events occur.

    Scenario : User pays too little and then tops up for full amount

    1. Payment form loads -> triplea.frameResized|<height> event occurs.
    2. User makes mistake by paying too little.
    3. Payment form informs user the remaining amount due -> triplea.paymentTooLittle and triplea.frameResized|<height> events occur.
    4. User tops up before payment form timer expires -> triplea.paymentSuccess and triplea.frameResized|<height> events occur.

    Page Redirection

    By providing a success_url and cancel_url in the request body when making a payment request call, the embedded payment form will then redirect the whole (parent) page to either of those URLs depending on the payment outcome.

    If you prefer to avoid a full page redirect , don't provide the URLs and use the postMessage events above to customize the behaviour.

    For example:

    • You may use the triplea.paymentSuccess event to display a success message instead of staying on the payment form.

    Content Management System (CMS) Plugins

    Some of the features with this integration:

    • Create an account and activate instantly.
    • Setup the plugin within seconds.
    • Automatic Order Updates.

    Our TripleA's integration is available in :

    1. WooCommerce plugin.
    2. OpenCart plugin.

    Custom Integration

    If you want to integrate TripleA into a Point-Of-Sale system or you require more flexiblity to suit your particular needs, please contact us at support@triple-a.io and we will assist you with the integration.

    Refunds and Withdrawals

    For refunds and withdrawals, cryptocurrency is returned to the customer. The merchant must have sufficient available balance to cover the refund or withdrawal. real available balances are used to refund or withdraw actual cryptocurrency while test available balances can only be used to refund or withdraw testnet cryptocurrency.

    Refunds

    The amount of cryptocurrency returned does not depend on the amount of cryptocurrency sent, but the amount of local currency that is received as payment. The maximum amount that can be refunded cannot exceed the local currency amount received.

    This is the refund flow:

    1. A refund is initiated against a payment. The email address of the refund recipient is provided.

    2. The refund recipient gets an email informing them of their refund. There is a link in the email that they can click.

    3. By clicking on this link, the refund recipient is brought to a form where they can see how much cryptocurrency they will receive for the refunded local currency. Only on clicking the link will the exchange rate for this conversion be fixed. The recipient then needs to enter in the crypto address where they would like to receive the crypto funds and confirm it.

    4. The merchant should receive a notification email once the refund recipient has confirmed their crypto address.

    5. Once the transfer of cryptocurrency has been made, another notification email will be sent to the merchant. There will also be a corresponding payout webhook notification.

    Withdrawals

    The total amount of cryptocurrency that can be withdrawn from a merchant depends on the amount of available balance the merchant has.

    This is the withdrawal flow:

    1. A withdrawal is initiated against a merchant's available balance. The email address of the withdrawal recipient is provided.

    2. The withdrawal recipient gets an email informing them of their withdrawal. There is a link in the email that they can click.

    3. By clicking on this link, the withdrawal recipient is brought to a form where they can see how much cryptocurrency they will receive for the withdrawn local currency. Only on clicking the link will the exchange rate for this conversion be fixed. The recipient then needs to enter in the crypto address where they would like to receive the crypto funds and confirm it.

    4. The merchant should receive a notification email once the withdrawal recipient has confirmed their crypto address.

    5. Once the transfer of cryptocurrency has been made, another notification email will be sent to the merchant. There will also be a corresponding payout webhook notification.

    Webhook Notification Security

    If you would like to verify the authenticity of a webhook notification, we provide a signature in the Triplea-Signature HTTP header.

    The header has the format t=<unix-timestamp>,v1=<hex-encoded-signature> where t is the unix timestamp and v1 is the hex-encoded signature.

    A shared secret (notify_secret) is used to verify this signature and can either be:

    1. Provided by you during the payment request, refund or withdrawal. You may reuse the same secret.

    2. Generated by the system, if no secret is provided during the payment request, refund or withdrawal. This will be a random secret that only applies for that particular payment request, refund or withdrawal.

    To verify the header signature, the developer will take the timestamp and concatenate it with the raw request body, using a period . as a separator <unix-timestamp>.<raw-request-body> and apply the hmac-sha256 algorithm with notify_secret. This gives a signature which can be compared to the v1 from the HTTP header.

    If the signatures match, compare the t against the current timestamp. If they are within tolerance then the webhook is authenticated. The recommended tolerance is 300 seconds.

    Here is some sample Node.js code for signature verification using express:

    'use strict';
    
    // crypto module
    const crypto = require('crypto');
    
    // This example uses Express to receive webhooks
    const app = require('express')();
    
    // Use body-parser to retrieve the raw body as a buffer
    const bodyParser = require('body-parser');
    
    const secret = 'Cf9mx4nAvRuy5vwBY2FCtaKr!@#';
    
    // Match the raw body to content type application/json
    app.post(
      '/webhook', 
      bodyParser.raw({type: 'application/json'}), 
      (req, res) => {
        const sig = req.headers['triplea-signature'];
    
        let timestamp, signature;
        for (let sig_part of sig.split(',')) {
          let [key, value] = sig_part.split('=');
    
          switch (key) {
            case 't':
              timestamp = value;
              break;
            case 'v1':
              signature = value;
              break;
          }
        }
    
        // calculate signature
        let check_signature = crypto.createHmac('sha256', secret)
          .update(`${timestamp}.${req.body}`)
          .digest('hex');
    
        // current timestamp
        let curr_timestamp = Math.round((new Date()).getTime() / 1000);
    
        if (
          signature === check_signature && // verify signature
          Math.abs(curr_timestamp - timestamp) <= 300 // timestamp within tolerance
        ) {
          // signature validates ... do stuff
          return res.status(200).end();
        } else {
          return res.status(400).end();
        }
      }
    );
    
    app.listen(10003, () => console.log('Listen to 10003'));
    

    Payment Notification And Instant Confirmation

    TripleA sends payment notifications to your payment notification webhook via an HTTP POST. Every time a buyer sends a Bitcoin transaction to a payment address, it generates 2 payment notifications. One when the transaction is broadcast and the other when the transaction is added to the blockchain.

    For the payment notification and Instant Confirmation, payment_tier and the payment_amount are the most important things to consider, to determine how much money you will receive and whether to deliver the goods and services.

    The payment_tier is the overall state of the payment and it can be in 1 of 5 states: none, short, hold, good and invalid

    1. none - no payment has been detected (yet). The merchant should not deliver the goods and services.

    2. short - the payment is short of the requested amount. The merchant should not deliver the goods and services.

    3. hold - the payment is equal to or greater then the requested amount, but the payment cannot be instantly confirmed. The merchant should not deliver the goods and services.

    4. good - the payment is equal to or greater then the requested amount and TripleA has determined that you can now deliver the goods and services to the buyer. 97% of transactions that we process have instant confirmation and are determined good within a few seconds of being broadcasted to the Bitcoin network. Your funds are now guaranteed.

    5. invalid - the payment was rejected by the Bitcoin network. This is a very rare occurence.

    The payment_amount is the guaranteed amount of local currency that you will receive. Even if the payment_tier remains as short or hold or later becomes invalid.

    Payment Tier Progression

    1. A none payment can go to : short, hold, good or invalid.

    2. A short payment can go to: hold, good or invalid.

    3. A hold payment can go to: good or invalid.

    4. A good payment is always good, no matter what actually happens on the blockchain.

    5. A invalid payment is always invalid as it has been rejected by the blockchain.

    Payment Stages

    Payment Notification Schema

    event
    string

    Type of webhook notification event. In this case payment

    api_id
    string

    The API ID of the cryptocurrency wallet the funds will be received in. You can either use a "live" API ID or a sandbox API ID

    payment_reference
    string

    Unique Payment Reference Number that identifies this payment

    crypto_currency
    string

    Cryptocurrency that the payer will pay

    crypto_address
    string

    Address that the customer must send the cryptocurrency funds to. Each address will only be used to receive a single payment

    crypto_amount
    number <float>

    Amount of cryptocurrency to be sent to the address

    order_currency
    string

    Currency that the merchant will receive. This should be a 3-character ISO 4217 currency code

    order_amount
    number <float>

    The amount of currency that the merchant wants to receive

    exchange_rate
    number <float>

    Exchange rate that is used to calculate the required crypto_amount

    expiry_date
    string <date-time>

    Exchange rate is guaranteed until the expiry date. After expiry, any cryptocurrency funds received by the address will be converted at the spot exchange rate

    unconfirmed_crypto_amt
    number <float>

    Amount of cryptocurrency received by the crypto_address that has been detected but is still unconfirmed.

    Note: This amount describes part of the state of the payment on the blockchain. Please use only if you need more information with regards to the state of the payment on the blockchain.

    unconfirmed_order_amt
    number <float>

    Amount of local currency that has been detected but is still unconfirmed.

    Note: This amount describes part of the state of the payment on the blockchain. Please use only if you need more information with regards to the state of the payment on the blockchain.

    confirmed_crypto_amt
    number <float>

    Amount of cryptocurrency received by the crypto_address that has been confirmed.

    Note: This amount describes part of the state of the payment on the blockchain. Please use only if you need more information with regards to the state of the payment on the blockchain.

    confirmed_order_amt
    number <float>

    Amount of local currency that has been confirmed.

    Note: This amount describes part of the state of the payment on the blockchain. Please use only if you need more information with regards to the state of the payment on the blockchain.

    status
    string
    Enum: "unpaid" "unconfirmed-less" "unconfirmed" "unconfirmed-more" "confirmed-less" "confirmed" "confirmed-more"

    These are the statuses:

    1. unpaid - no payment is made or detected.

    2. unconfirmed-less - payment is unconfirmed and is less than the amount requested in local currency.

    3. unconfirmed - payment is unconfirmed and is equal to the amount requested in local currency.

    4. unconfirmed-more - payment is unconfirmed and is greater than the amount requested in local currency.

    5. confirmed-less - payment is confirmed and is less than the amount requested in local currency.

    6. confirmed - payment is confirmed and is equal to the amount requested in local currency.

    7. confirmed-more - payment is confirmed and is greater than the amount requested in local currency.

    Note: These statuses describe the overall state of the payment with respect to the blockchain. Please use only if you need more information with regards to the state of the payment on the blockchain.

    status_date
    string <date-time>

    Date and time the status was updated

    payment_tier
    string
    Enum: "none" "short" "hold" "good" "invalid"

    Payment tiers describe the overall state of the payment and are related to Instant Confirmation. These are the tiers:

    1. none - no payment has been detected (yet). The merchant should not deliver the goods and services.

    2. short - the payment is short of the requested amount. The merchant should not deliver the goods and services.

    3. hold - the payment is equal to or greater then the requested amount, but the payment cannot be instantly confirmed. The merchant should not deliver the goods and services.

    4. good - the payment is equal to or greater then the requested amount and TripleA has determined that you can now deliver the goods and services to the buyer. 97% of transactions that we process have instant confirmation and are determined good within a few seconds of being broadcasted to the Bitcoin network. Your funds are now guaranteed.

    5. invalid - the payment was rejected by the Bitcoin network. This is a very rare occurence.

    payment_tier_date
    string <date-time>

    Date and time the payment_tier was updated

    payment_amount
    float

    Guaranteed amount of local currency that the merchant will receive. Even if the payment_tier remains as short or hold or later becomes invalid.

    cart
    object (Cart)

    Shopping Cart

    webhook_data
    object (WebhookData)

    This data will be passed through to the webhook during payment notification. It is a JSON object that can contain any information that the merchant want’s to pass through to the webhook.

    We recommend that you at least include the order_id which ties this payment request to the order in your system. You can also include any other data you need to be passed through to your payment notification webhook