Carbon

Documentation

Welcome to Carbon's docs!

Get Started    

Payment Gateway Widget

Example Integration

Please go here for code on an example integration of our payment gateway widget: https://github.com/stablecarbon/fiber_checkout_example.

Overview

Provide a secure & seamless payments experience for your users.

The payment gateway widget is available at https://card.carbon.money and should be enclosed in an iframe for integration. There are two main components that you will have to render at various points in the iframe highlighted below. In addition, you will have to use your backend to begin charge of a payment card on our side given its tokenized fields.

  1. The first component you will have to render in the iframe is a card form where your users will add and submit their payment card data. If submission is successful, you will receive a tokenized card object.
  2. You will then use the returned tokenized card info to add and charge a payment card and create an order via the Carbon Fiber Credit/Debit Card API checkout endpoint.
    3.. You can then use the returned order id from the checkout endpoint above to render the 3DS authentication ACS (Access Control Server) form.
    4.. After 3DS authentication finishes, complete processing the payment at your (optional) termination URL. If a custom termination URL is not set, you can handle completing authorization of the charge via the standard charge completion flow.

postMessage API

Use the postMessage API to securely communicate across origins
from this app's parent window to the child payment gateway widget window
in addition to responding to messages from the card.carbon.money frame. For more on the postMessage API, please refer to: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage. The following code samples for highlighting integration of the payment gateway widget will also demonstrate the 'postMessage' API in action.

0. Load card.carbon.money payment gateway widget in iFrame

Example code

<--- Load the payment gateway widget here from https://card.carbon.money.
     The card form dimensions are around 335px X 290px,
     so you can adjust the size of your checkout iframe accordingly. !--> 
<iframe
        id="paymentGatewayIframe"
        title="Carbon Payment Gateway Iframe"
        width="335"
        height="290"
        allow="fullscreen"
        src="https://card.carbon.money"
 />

The following code assumes your iframe integration of the card.carbon.money payment gateway widget is available via an HTML element with id 'paymentGatewayIFrame'

1. Collect and tokenize payment card info

Example code

// access payment gateway widget iframe window
const iframeWindow = document.getElementById('paymentGatewayIframe').contentWindow;
/**
     * Use the `postMessage` API to render the card form in the payment gateway iframe with two parameters:
     *   1. your superuser public key ('publicKey') for authentication
     *   2. the target environment ('env'). options are 'sandbox' or 'production'.
     * */
iframeWindow.postMessage(
  {
    type: 'renderCardForm',
    publicKey: process.env.REACT_APP_SANDBOX_PUBLIC_KEY,
    env: 'sandbox',
  }, '*',
);

// Add event handler in parent window for receiving messages
// from payment gateway widget iframe to initiate checkout
window.addEventListener('message', receiveIframeMessage, false);


If the card form submission is successful, the 'paymentGatewayIframe' will communicate via the 'postMessage' API the tokenized payment card fields to the parent app window. As in the code sample above, we assume you added an event handler called 'receiveIframeMessage' to your window to handle messages from our payment gateway iframe. The superuser can use this token card object to initiate checkout. For more on that flow below.

Sandbox Testing

For card details to test in the sandbox environment, refer back to Sandbox Testing Information

2. Add and charge a payment card for checkout (POST), 3. Initiate 3DS authentication via ACS form

Payment Gateway v Credit/Debit Purchases API

The payment gateway can be thought of as a configured extension of the credit/debit purchases API. For example, the checkout widget utilizes the same tokenization functionality highlighted here API integrators can utilize (NOT recommended given the increased PCI exposure) in addition to ACS functionality highlighted here. Similarly, you can use this same endpoint to add a card on our side with tokenized fields v not tokenized fields as highlighted here. It is strongly recommended to review our core credit/debit API doc section in conjunction with our payment gateway docs to make sure you understand the differences between a payment gateway v not payment gateway integration.

Note that the below checkout endpoint combines the functionality of our /v1/card/addNew and /v1/card/charge3d endpoints into one route for initiating a payment with a credit/debit card. It is strongly recommended you review documentation on those endpoints while integrating this checkout endpoint.

Superuser and Contact Auth Required

Example request/response for checkout frontend integration

/** 
   * Handler for receiving messages from payment gateway widget iframe
   * via the `postMessage` API.
   *
   * After accessing the message data object in the 'data' field, you should
   * handle one message type in particular: 'tokenizationSuccess'.
   * You can access the message type by accessing the 'type'
   * field in the message data object. The 'tokenizationSuccess' message is
   * transmitted to the parent window from card.carbon.money when a card is
   * successfully submitted and tokenized via the rendered card form.
   * The tokenized card object will be available in the 'tokenizationSuccess'
   * message 'data' field. We then use the tokenized card object to initiate
   * checkout via the proxy server checkout endpoint, which calls the Carbon
   * Fiber /v1/card/checkout endpoint to add and begin charging a card for
   * payment.
   *
   * If checkout is successful, you will receive an order id. You can then use
   * that order id in addition to your superuser public key to begin the 3DS
   * authentication process for the order in the designated environment.
   * Again you can use the `postMessage` API to send a message of type
   * `renderACSForm` with the above parameters to render the ACS form. If 3DS
   * authentication is successful, you can then complete payment.
   * Note that this example integration assumes the superuser has set a
   * `customTermUrl` where the superuser can then decide to either not complete
   * payment or complete payment by posting to our charge completion
   * url with their order id.
  **/
const receiveIframeMessage = (e) => {
  // comment out below console logs to debug
  // console.log('Handling message.');
  // console.log(e);
  // console.log('Message origin.');
  // console.log(e.origin);
  // console.log('Message data passed.');
  // console.log(e.data);
  const data = { ...e.data };
  if (data.type === 'tokenizationSuccess') {
    // console.log('Card form submitted and card tokenized. Here is card token data.');
    // console.log(data.data);
    // checkout backend integration example highlighted later
    axios.post('/checkout', data.data)
      .then((resp) => {
      // console.log('Checkout success response data.')
      // console.log(resp.data);

      const iframeWindow = document.getElementById('paymentGatewayIframe').contentWindow;
      /**
           * Use the `postMessage` API to render the 3DS authentication ACS form
           * in the payment gateway widget iframe with the following three parameters:
           *   1. your superuser public key ('publicKey') for authentication
           *   2. the target environment ('env'). options are 'sandbox' or 'production'
           *   3. the order id for checkout ("orderId")
           * */
      iframeWindow.postMessage(
        {
          type: 'renderACSForm',
          publicKey: process.env.REACT_APP_SANDBOX_PUBLIC_KEY,
          env: 'sandbox',
          orderId: resp.data.details.orderId,
        }, '*',
      );
    })
      .catch((err) => {
      console.log('Error checking out.');
      console.log(err);
    });
  }
};

Secret Auth v Legacy Auth

While you can use your superuser JWT to add a tokenized credit/debit card, we strongly recommend using your secret key to authenticate. The request authorization header is exactly the same except you substitute your secret key for the JWT.

If you do not know your secret key, please reach out to [email protected] from your superuser email.

Example request/response for checkout backend integration

// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';

let headers = {
  headers: {
    Authorization: `Bearer ${secretKey}`
  }
};

let tokenObject = {
  billingPostal: 'tok_sandbox_cX7qASdFWyDY3KbCXUZeMs',
  billingPremise: 'tok_sandbox_tbLwipMuUxoqZcwXuKwv8w',
  billingStreet: 'tok_sandbox_cQJ8WxYtgNj2faEiu61sP6',
  cardNumber: 'tok_sandbox_wCGBiawWVS2AX1rQfDj4x7',
  cvc: 'tok_sandbox_381fpMbdzMwyaoeiSKg732',
  expiry: 'tok_sandbox_eoXXh6Et8bssJD7r4bRGfF' 
};

 let data = {
   tokenObject: tokenObject, 
   contactId: '', 
   fiatBaseCurrency: "usd",
   fiatChargeAmount: "1000"
};

let url = `${ROOT}/v1/card/checkout`;

axios.post(url, data, headers).then(result => console.log(result)).catch(err => console.log(err));
{
  message: 'Success checking out',
  code: 200,
  details: 
  { orderId: '86d74252-44ea-419f-93cc-9c09ac19c78d'
 } 
}
// also check out the /v1/card/addNew and /v1/card/charge3D 
// error documentation mentioned earlier
// as we relay error responses from those endpoints to /v1/card/checkout

// 400
{
  message: "'tokenObject' must include the following fields: 
        'cardNumber', 'expiry', 'cvc', 'billingPremise', 'billingStreet', 'billingPostal'",
  code: 400
}

// 429
{
 message: 'Card is not enrolled in 3D Secure. Please try a different card.'
 code: 429,
 details: {
   charge3denrolled: 'N'
 }
}

// 429
{
 message: 'Card has an unknown enrollment in 3D Secure. Please try again or try a different card if the problem persists.'
 code: 429,
 details: {
   charge3denrolled: 'U'
 }
}

// 500
{
  message: 'There was an error checking out.',
  code: 500
}
Parameters
Access
Description

contactId

required

fiatBaseCurrency

required

The settlement currency for the crypto purchase. Case-insensitive. Must be a valid three-character ISO 4217 currency code. For a list of ISO 4217 codes go to this link: https://www.iban.com/currency-codes and check out our list of supported fiat base currencies here. Note that as mentioned above FX from the user's local currency of their credit/debit card to the settlement currency is automatic and specific rates are determined by the user's issuing bank.

fiatChargeAmount

required

The amount you'd like to charge a card. You need to pass in a string without any decimals. For example a charge of $10.39 would be rendered as "1039" and $233.91 would be "23391".

tokenObject

required

Tokenized credit/debit card fields. Will/must have the following keys: 'cardNumber', 'expiry', 'cvc', 'billingPremise', 'billingStreet', 'billingPostal'. For more information, please check out this.

3DS Enrollment

Make sure to reference the error responses in the example code section above for handling when payment cards are not enrolled in 3D Secure or when payment cards have an unknown 3DS enrollment.

4. Complete payment

Please go here to learn more about completing processing for payments after 3DS authentication finishes. This subsection will also be expanded soon.

Updated 20 days ago

Payment Gateway Widget


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.