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. This repo will be actively updated in the near future so stay tuned for updates and improvements!

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. There are certain optional parameters for the card form you can set we highlight in a note below.
  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.**

**For now custom termination URL config is not set up. Please set your customTermUrl to undefined to avoid breaking code.

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.

Optional Parameters for Card Form

There are the current optional parameters you can set for the card form: ['hideBillingPostal', 'hideBillingStreet', 'hideTitle', 'hideSubmit', 'styles'].

  1. hideBillingStreet: Remove the billing street field from the card form. You will later have to include your contact's tokenized billing street on your end before checking out or have already set your contact's default billing street as demonstrated here: https://docs.carbon.money/docs/contacts#section-8-patch-contact-patch
    1. hideBillingPostal: Remove the billing postal code field from the card form. You will later have to include your contact's tokenized billing postal code on your end before checking out or have already set your contact's default billing postal code as demonstrated here: https://docs.carbon.money/docs/contacts#section-8-patch-contact-patch
  2. hideTitle: Hide our title Payment Info at the top left of the card form.
  3. hideSubmit: Hide our default submit button from the card form. You can then implement your own submit button instead. You can then initiate submission of the card form by using the postMessage API to send the following message: { type: 'submitForm' }. No other parameters in the message are needed.
    1. styles: Customize styling of card input fields (cardNumber, expiry, cvc). Use React inline style convention for styles object camelcase properties: https://reactjs.org/docs/dom-elements.html#style.

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

Example code

<--- Load the payment gateway widget here from https://card.carbon.money.
     Update styling as you see fit for your integration. !--> 
 <iframe
   id="paymentGatewayIframe"
   title="Carbon Payment Gateway Iframe"
   style={
     {
       width: '100%',
       height: '100%',
       border: 'none'
     }
   }
   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

// The following are optional render card form parameters.
// These are unpacked more above the `renderCardForm` call.
  const hideBillingPostal = true, hideBillingStreet = true, hideTitle = true, hideSubmit  = true;
const styles =  {
  fontSize: '16px',
};

// 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 required parameters:
     *   1. your superuser public key (`publicKey`) for authentication
     *   2. the target environment (`env`). options are 'sandbox' or 'production'.
     * 
     * The following parameters are optional:
     *    1.  `hideBillingStreet`: Remove the billing street field from the card form. You will later have to include your
     *        contact's tokenized billing street on your end before checking out or have already set your contact's 
     *        default billing street as demonstrated here: https://docs.carbon.money/docs/contacts#section-8-patch-contact-patch
     *    2. `hideBillingPostal`: Remove the billing postal code field from the card form. You will later have to include your
     *        contact's tokenized billing postal code on your end before checking out or have already set your contact's 
     *        default billing postal code as demonstrated here: https://docs.carbon.money/docs/contacts#section-8-patch-contact-patch
     *    3. `hideTitle`: Hide our title `Payment Info` at the top left of the card form.
     *    4. `hideSubmit`: Hide our default submit button from the card form. You can then implement your own submit button instead. 
     *       You can then initiate submission of the card form by using the `postMessage` API to send the following message: { type: 'submitForm' }. No other parameters in the message are needed.
     *    5. `styles`: Customize styling of card input fields (cardNumber, expiry, cvc). Use React inline style convention for `styles` object camelcase properties: https://reactjs.org/docs/dom-elements.html#style.

     * */
    iframeWindow.postMessage(
      {
        type: 'renderCardForm',
        publicKey: process.env.REACT_APP_SANDBOX_PUBLIC_KEY,
        env: 'sandbox',
        hideBillingStreet,
        hideBillingPostal,
        hideTitle,
        hideSubmit,
        styles,
      }, '*',
    );


// 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. You can also access from our dashboard available here by logging into your developer account.

Example request/response for checkout backend integration

Client IP Address

Make sure to pass in your user's ip address under the 'userip' request header! We are required for compliance reasons to collect data on the location of our users. For more information on our location tracking policies, please go here.

// 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}`,
    userip: '68.251.59.34' // replace with your user's ip address
  }
};

  // if you configured the card form to to hide the billing street and/or billing postal code fields, 
    // you will have to tokenize those fields (along with the billing premise) separately on your end 
    // and then supply the `tokenizedBillingStreet`, `tokenizedBillingPremise`, and `tokenizedBillingPostal` 
    // fields at checkout as detailed here: https://docs.carbon.money/docs/checkout-widget#section-example-request-response-for-checkout-backend-integration. 
    // You can also set the contact's default `billingStreet` and `billingPostalCode` as detailed here: 
    // https://docs.carbon.money/docs/contacts#section-8-patch-contact-patch
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',
    issuingCountry: 'US',
    cardScheme: 'VISA',
    // sha-256 hash of card number and expiration date
    uniqueHash:
    '6a7bc947b94eba36e7451ebf347914521129103b46335a4188114f25bc153da4',
    last4: '0511' 
 } 
}
// 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 21 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.