Omise

Overview

This guide will help you integrate the Omise payment gateway into your Chec/Commerce.js storefront using Omise.js. As of writing, you are required to use Omise.js when working with the Omise payment gateway.

Omise JS can be integrated in two ways.

1.Pre-built payment form This form securely handles collecting, validating, and sending user data to the Omise servers. It also collects additional data from the user's browser to help protect against fraud.

2.Request Tokens & Sources directly - This approach provides the most flexibility, and has full support for all payment methods provided by Omise but you are required to create your own form, and handle all events.

In this guide

1.Overview of the payment flow for processing payments with the Omise gateway

2.Example application implementation - Integrate the Omise.js pre-built payment form JavaScript library in your application (Pre-built payment form integration method) - Connect a custom input form to Omise.js (Request Tokens & Sources directly method) - Example implementation of capturing a checkout with Chec/Commerce.js

Payment flow

In this guide, debit/credit card (card) & TrueMoney Wallet (source) processing will be used as the payment methods. Other payment sources like AliPay, Rabbit Line Pay, or PayNow will not be shown. For more information on other methods, read supported payment methods and sources.

Omise.js must first be called and a token or source id must be returned first before calling the checkout capture API.

Requirements and prerequisites

  • Chec account with Omise gateway enabled
  • To support sources e.g. TrueMoney Wallet, Rabbit Line Pay, Prompt Pay you will also need to enable webhooks on your Omise account.
  • Credentials: Omise public live key for production or test key for non-live transactions
  • Node.js and npm
  • Some knowledge with JavaScript

Example implementations

Step by step

  1. Load Omise.js into your checkout and setup your public key with Omise.
  2. Embed the pre-built Omise checkout form into your checkout page, or connect your custom credit card form to Omise.js.
  3. Use Omise.js to create a payment token
  4. Use Commerce.js to charge the payment source with the generated token and send the data to the Chec API.
Important

You need to pass the correct order total in the smallest unit to Omise.js.

  • You can find the order total in the live object live.total_with_tax.raw
  • Convert this amount into the smallest unit (usually the subunit) for your currency currency.
    • e.g. For the smallest unit of Thai Baht is 1/100 of a baht, so you need to specify 12300 to indicate ฿123.

Learn more: https://www.omise.co/currency-and-amount

Important! To support sources you need to setup your Omise webhook

If you are planning on using alternative payment methods e.g. PromptPay, TrueMoney etc you will need to add the following webhook in the Omise dasboard.

https://api.chec.io/v1/listeners/omise/webhook

After a successful checkout capture request, an order made with a non credit/debit card payment with be created in a pending, unpaid, and unfulfilled state. Only when we receive a confirmation webhook from Omise will the order be processed normally.

Load the Omise.js library and insert your public key

Install Omise.js by including the following script in your webpage.

<script type='text/javascript' src='https://cdn.omise.co/omise.js'></script>

If you’re using React, you can use the unofficial use-omise React hook library created by Chris Vibert.

Next we need to set your public key up with Omise.

<script type='text/javascript'>
  Omise.setPublicKey('<OMISE_PUBLIC_KEY>'); 
</script>
Note

We return all gateway public keys in our checkout token response objects, you can access it with the following key

gateways.omise.settings.public_key

Integrating with the Omise.js pre-built payment form

The simplest way to work with Omise is to integrate their hosted checkout (https://www.omise.co/omise-js#pre-built-payment-form)

<form id='paymentForm'>
    <input id='omiseToken' name='omiseToken' type='hidden'/>
    <input id='omiseSource' name='omiseSource' type='hidden'/>

    <input id='captureOrder' type='submit' value='Submit'>
</form>

<script>
  OmiseCard.configure({
    publicKey: '<OMISE_PUBLIC_KEY>'
  });

  var button = document.querySelector('#captureOrder');
  var form = document.querySelector('#paymentForm');

  button.addEventListener('click', (event) => {
    event.preventDefault();
    OmiseCard.open({
      amount: parseFloat(live.total_with_tax.raw) * 100, //The order total in the smallest unit for the currency
      currency: live.currency.code,
      onCreateTokenSuccess: (nonce) => {
        if (nonce.startsWith('tokn_')) {
          form.omiseToken.value = nonce;
          alert('Card token created: ' + nonce);
        } else {
          form.omiseSource.value = nonce;
          alert('Source token created: ' + nonce);
        }
      }
    });
  });
</script>

Once you have your card token or your source id you can pass the data along with the rest of the customer and order data to commerce.checkout.capture()

commerce.checkout.capture(checkoutToken, {
  ...orderData,
  payment: {
    gateway: 'omise',
    omise: {
      source: document.getElementById('omiseSource') // The returned Omise source id
      // OR
      token: document.getElementById('omiseToken') // The returned Omise token id
    },
  },
}).then((order) => {
  // Payment and order capture was successful, and the order detail is provide in the order variable.
  console.log(order);
  alert('Payment completed successfully!\nCheck browser developer console for more details');
}).catch((err) => {
  // Error handling for when the payment fails with Square
  console.error(err);
  alert('Payment failed to complete!\nCheck browser developer console for more details');
});

Integrating with directly Omise.js

If you want to create and render your own credit card or source input fields you can do so by collecting data via your own input fields.

<form id='payment-form'>
    <div id='credit-card-fields'>
        <input type='text' id='cardholderName' name='cardholderName'>
        <input type='number' id='cardNumber' name='cardNumber'>
        <input type='number' id='expiryMonth' name='expiryMonth'>
        <input type='number' id='expiryYear' name='expiryYear'>
        <input type='number' id='securityCode' name='securityCode'>
        <!-- For more details on what credit card details you can pass to Omise.js
        Visit - https://www.omise.co/omise-js#omise-methods !-->
    </div>

    <div id='source-fields'>
        <input type='number' id='phoneNumber' name='phoneNumber'>
        <!-- For more details on what source details you can pass to Omise.js
        Visit - https://www.omise.co/sources-api#create !-->
    </div>

    <!-- here you can specify any other fields you have in your checkout !-->

    <!-- insert a button to submit the form -->
    <input type='button' value='Submit' onclick='captureOrder()'>
</form>

Capture a checkout with an Omise Token (Card payment)

Next step is to create your capture order function to create a Omise token.

// Create a capture checkout function that will be called when a 'pay now' button is clicked
const captureOrder = () => {
  // Data from form input
  const cardData = {
    name: document.getElementById('cardholderName'),
    number: document.getElementById('cardNumber'),
    expiration_month: document.getElementById('expiryMonth'),
    expiration_year: document.getElementById('expiryYear'),
    security_code: document.getElementById('securityCode')
  };

  // Send data to Omise.js
  Omise.createToken('card', cardData, (statusCode, response) => {
    // Handle error
    if (response.object === 'error') {
      console.log(response.message);
      return;
    }
    // Token was created successfully and can be sent to backend.
    console.log(response.id);

    // To add payment submission with token
    commerce.checkout.capture(checkoutToken, {
      ...orderData,
      payment: {
        gateway: 'omise',
        omise: {
          token: response.id
          // The returned omise token
        },
      },
    }).then((order) => {
      // Payment and order capture was successful, and the order detail is provide in the order variable.
      console.log(order);
      alert('Payment completed successfully!\nCheck browser developer console for more details');
    }).catch((err) => {
      // Error handling for when the payment fails with Omise
      console.error(err);
      alert('Payment failed to complete!\nCheck browser developer console for more details');
    });
  });
}

Capture a checkout with an Omise Source (E.g. Prompt Pay, Alipay etc)

// Create a capture checkout function that will be called when a 'pay now' button is clicked
const captureOrder = () => {
  const orderData = {
    // ... get your order data from your checkout form
    payment: { gateway: 'omise' },
  };

  const sourceData = {
    amount: parseFloat(live.total_with_tax.raw) * 100, // The order total in the smallest unit for the currency
    currency: live.currency.code,
    phoneNumber: document.getElementById('phoneNumber')
    type: 'truemoney' // See https://www.omise.co/sources-api#create for more
  };

  Omise.createToken('source', sourceData, (statusCode, response) => {
    // Handle error
    if (response.object === 'error') {
      console.log(response.message);
      return;
    }

    // To add payment submission with token
    commerce.checkout.capture(checkoutToken, {
      ...orderData,
      payment: {
        gateway: 'omise',
        omise: {
          source: response.id //The returned Omise source id
        },
      },
    }).then((order) => {
      // Payment initiated.
      console.log(order);
      alert(
        'Payment initiated, please check payment_source for more information!\nCheck browser developer console for more details');
    }).catch((err) => {
      // Error handling for when the payment fails with Omise
      console.error(err);
      alert('Payment failed to complete!\nCheck browser developer console for more details');
    });
  });
}

Complete/Authorize an Omise Source payment (E.g. Prompt Pay, Alipay etc)

After a successful checkout capture request in the transactions.payment_source key you will see data provided by Omise Source API, this data contains what you need to authorize & complete an offine/alternative payment request.

E.g. For PromptPay you will see the QR code that you need to display to your customer so they can authorize the payment in their banking app.

{
  "transactions": [
    {
      "id": "trns_kpnNwAqKjxwmXB",
      "type": "charge",
      "status": "pending",
      "status_reason": "awaiting_authorization",
      "charge_date": 1629301618,
      "gateway": "omise",
      "gateway_name": "Omise",
      "gateway_transaction_id": "chrg_test_5ovu35mjhfmj4iqgwwe",
      "gateway_reference": "",
      "notes": "",
      "amount": {
        "raw": 10000,
        "formatted": "10,000.00",
        "formatted_with_symbol": "฿10,000.00",
        "formatted_with_code": "10,000.00 THB"
      },
      "payment_source_type": "promptpay",
      "payment_source": {
        "source_id": "src_test_5ovu317g7avcezo6duj",
        "type": "promptpay",
        "scannable_code": {
          "object": "barcode",
          "type": "qr",
          "image": {
            "object": "document",
            "livemode": false,
            "id": "docu_test_5ovu35nrj488pyardtq",
            "deleted": false,
            "filename": "qrcode_test.svg",
            "location": "/charges/chrg_test_5ovu35mjhfmj4iqgwwe/documents/docu_test_5ovu35nrj488pyardtq",
            "kind": "qr",
            "download_uri": "https://api.omise.co/charges/chrg_test_5ovu35mjhfmj4iqgwwe/documents/docu_test_5ovu35nrj488pyardtq/downloads/B5B5567E0D05CFDE",
            "created_at": "2021-08-18T15:46:58Z"
          }
        },
        "barcode": null,
        "installment_term": null,
        "references": null,
        "bank": null,
        "zero_interest_installments": null,
        "name": null,
        "email": null,
        "mobile_number": null,
        "store_id": null,
        "store_name": null,
        "terminal_id": null
      },
      "created": 1629301618,
      "updated": 1629301618,
      "dunning": {
        "is_dunning": false,
        "failed_attempts": 0,
        "last_failed_attempt": null,
        "next_attempt": null
      }
    }
  ]
}