Skip to content

Instantly share code, notes, and snippets.

@jagdeepsingh
Last active September 19, 2017 12:40
Show Gist options
  • Save jagdeepsingh/730549bf41ffbe8cc7d28d984c8c3893 to your computer and use it in GitHub Desktop.
Save jagdeepsingh/730549bf41ffbe8cc7d28d984c8c3893 to your computer and use it in GitHub Desktop.
Omise-Payment Gateway

1 Setup merchant account on payment gateway

You can sign up on Omise here.

After sign up, you will be taken to a page where you will create a merchant account. Enter details, select your service provider and click "Create Account". Unless otherwise stated, following documentation assumes you have account on Omise Thailand service provider.

Now, you can access the dashboard at https://dashboard.omise.co/test/dashboard.

Under API > Keys, note down PUBLIC_KEY and SECRET_KEY.

The PUBLIC_KEY can be used to create tokens via javascript from your customers browsers. This key can be safely exposed to the outside world.

The SECRET_KEY can be used to create customers, cards and charges and to retrieve information about your account, such as its balance. You must keep this key from prying eyes.

Omise recommends the merchant to use client-side JS library to encrypt the credit card data by sending it directly to omise servers. But if you want to create a token on merchant server side, you'll need card data transiting to and from your server and this requires that your organization be PCI compliant.

Back to top

2 Installation

We are using omise-ruby to interact with Omise API for making payments.

Add it to Gemfile:

gem 'omise', '~> 0.7.0'

Run bundle install.

Back to top

3 Generate token from credit card details

Include omise.js in your webpage.

/ app/layouts/payments.html.slim
= javascript_include_tag 'https://cdn.omise.co/omise.js.gz'
// app/assets/javascripts/credit_card_encryption.js
window.CreditCardEncryption = (function() {
  function CreditCardEncryption() {}

  CreditCardEncryption.generateToken = function() {
    var card;
    Omise.setPublicKey(PUBLIC_KEY);
    card = {
      name: 'Jagdeep Singh',
      number: '4111111111111111',
      expiration_year: 2018,
      expiration_month: 11,
      security_code: '123'
    };
    return Omise.createToken('card', card, this.responseHandler);
  };

  CreditCardEncryption.responseHandler = function(statusCode, response) {
    if (statusCode === 200) {
      var token = response.id;
      console.log('Success');
    } else {
      console.log('Failure');
      console.log(response.message);
    }
  };

  return CreditCardEncryption;
})();

Back to top

4 Process payments

Test cards: https://www.omise.co/api-testing

If you have a single account, then you can set the secret key globally:

Omise.api_key = SECRET_KEY

But to use multiple accounts for different transactions, you will need to pass the SECRET_KEY in every request made to the API.

First generate a one-time-use TOKEN by passing credit card details to Omise API. Then, you can use that TOKEN to create customer on Omise.

Create customer with token

> args = { card: TOKEN,
           email: '[email protected]',
           description: 'This account belongs to Jagdeep Singh',
           metadata: {} }

# Do this if global secret key not set
> args[:key] = SECRET_KEY

> omise_customer = Omise::Customer.create(args)
=> #<Omise::Customer:0x007f96ecc986c0 @attributes={"object"=>"customer", "id"=>"cust_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001", "default_card"=>"card_test_10001", "email"=>"[email protected]", "description"=>"This account belongs to Jagdeep Singh", "metadata"=>{}, "created"=>"2017-07-13T07:31:31Z", "cards"=>{"object"=>"list", "from"=>"1970-01-01T00:00:00Z", "to"=>"2017-07-13T07:31:31Z", "offset"=>0, "limit"=>20, "total"=>1, "order"=>nil, "location"=>"/customers/cust_test_10001/cards", "data"=>[{"object"=>"card", "id"=>"card_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001/cards/card_test_10001", "country"=>"us", "city"=>nil, "postal_code"=>nil, "financing"=>"", "bank"=>"JPMORGAN CHASE BANK, N.A.", "last_digits"=>"1111", "brand"=>"Visa", "expiration_month"=>6, "expiration_year"=>2022, "fingerprint"=>"8VYaz0OJ7Lql+ddUCnHhWOqftGdyBX5FyUqSjAlYU2Q=", "name"=>"Frank Buffay", "security_code_check"=>true, "created"=>"2017-07-13T07:31:30Z"}]}}, @options={}, @expanded_attributes={}>

Purchase transaction

> args = { customer: omise_customer.id,
           currency: 'thb',
           amount: 1000 }
> args[:key] = SECRET_KEY
> omise_charge = Omise::Charge.create(args)
=> #<Omise::Charge:0x007fd94ab495a8 @attributes={"object"=>"charge", "id"=>"chrg_test_10001", "livemode"=>false, "location"=>"/charges/chrg_test_10001", "amount"=>1000, "currency"=>"thb", "description"=>nil, "metadata"=>{}, "status"=>"successful", "capture"=>true, "authorized"=>true, "reversed"=>false, "paid"=>true, "transaction"=>"trxn_test_10001", "source_of_fund"=>"card", "refunded"=>0, "refunds"=>{"object"=>"list", "from"=>"1970-01-01T00:00:00Z", "to"=>"2017-07-13T07:55:13Z", "offset"=>0, "limit"=>20, "total"=>0, "order"=>nil, "location"=>"/charges/chrg_test_10001/refunds", "data"=>[]}, "return_uri"=>nil, "offsite"=>nil, "offline"=>nil, "reference"=>nil, "authorize_uri"=>nil, "failure_code"=>nil, "failure_message"=>nil, "card"=>{"object"=>"card", "id"=>"card_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001/cards/card_test_10001", "country"=>"us", "city"=>nil, "postal_code"=>nil, "financing"=>"", "bank"=>"JPMORGAN CHASE BANK, N.A.", "last_digits"=>"1111", "brand"=>"Visa", "expiration_month"=>9, "expiration_year"=>2017, "fingerprint"=>"8VYaz0OJ7Lql+ddUCnHhWOqftGdyBX5FyUqSjAlYU2Q=", "name"=>"Thomas Patterson", "security_code_check"=>true, "created"=>"2017-07-13T07:54:56Z"}, "customer"=>"cust_test_10001", "ip"=>nil, "dispute"=>nil, "created"=>"2017-07-13T07:55:13Z"}, @options={}, @expanded_attributes={}>

The amount needs to be passed in the smallest unit of currency.

Authorize transaction

> args = { customer: omise_customer.id,
           currency: 'thb',
           amount: 1000,
           capture: false }
> args[:key] = SECRET_KEY
> omise_charge = Omise::Charge.create(args)
=> #<Omise::Charge:0x007f8615496040 @attributes={"object"=>"charge", "id"=>"chrg_test_10001", "livemode"=>false, "location"=>"/charges/chrg_test_10001", "amount"=>1000, "currency"=>"thb", "description"=>nil, "metadata"=>{}, "status"=>"pending", "capture"=>false, "authorized"=>true, "reversed"=>false, "paid"=>false, "transaction"=>nil, "source_of_fund"=>"card", "refunded"=>0, "refunds"=>{"object"=>"list", "from"=>"1970-01-01T00:00:00Z", "to"=>"2017-07-13T08:05:15Z", "offset"=>0, "limit"=>20, "total"=>0, "order"=>nil, "location"=>"/charges/chrg_test_10001/refunds", "data"=>[]}, "return_uri"=>nil, "offsite"=>nil, "offline"=>nil, "reference"=>nil, "authorize_uri"=>nil, "failure_code"=>nil, "failure_message"=>nil, "card"=>{"object"=>"card", "id"=>"card_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001/cards/card_test_10001", "country"=>"us", "city"=>nil, "postal_code"=>nil, "financing"=>"", "bank"=>"JPMORGAN CHASE BANK, N.A.", "last_digits"=>"1111", "brand"=>"Visa", "expiration_month"=>10, "expiration_year"=>2017, "fingerprint"=>"8VYaz0OJ7Lql+ddUCnHhWOqftGdyBX5FyUqSjAlYU2Q=", "name"=>"Kerry Johnson", "security_code_check"=>true, "created"=>"2017-07-13T08:04:57Z"}, "customer"=>"cust_test_10001", "ip"=>nil, "dispute"=>nil, "created"=>"2017-07-13T08:05:14Z"}, @options={}, @expanded_attributes={}>

Capture an authorized charge

> omise_charge = Omise::Charge.retrieve('chrg_test_10001', key: SECRET_KEY)

> omise_charge.capture(key: SECRET_KEY)
=> #<Omise::Charge:0x007fc62b115d70 @attributes={"object"=>"charge", "id"=>"chrg_test_10001", "livemode"=>false, "location"=>"/charges/chrg_test_10001", "amount"=>1000, "currency"=>"thb", "description"=>nil, "metadata"=>{}, "status"=>"successful", "capture"=>false, "authorized"=>true, "reversed"=>false, "paid"=>true, "transaction"=>"trxn_test_10001", "source_of_fund"=>"card", "refunded"=>0, "refunds"=>{"object"=>"list", "from"=>"1970-01-01T00:00:00Z", "to"=>"2017-07-13T11:12:50Z", "offset"=>0, "limit"=>20, "total"=>0, "order"=>nil, "location"=>"/charges/chrg_test_10001/refunds", "data"=>[]}, "return_uri"=>nil, "offsite"=>nil, "offline"=>nil, "reference"=>nil, "authorize_uri"=>nil, "failure_code"=>nil, "failure_message"=>nil, "card"=>{"object"=>"card", "id"=>"card_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001/cards/card_test_10001", "country"=>"us", "city"=>nil, "postal_code"=>nil, "financing"=>"", "bank"=>"JPMORGAN CHASE BANK, N.A.", "last_digits"=>"1111", "brand"=>"Visa", "expiration_month"=>9, "expiration_year"=>2017, "fingerprint"=>"8VYaz0OJ7Lql+ddUCnHhWOqftGdyBX5FyUqSjAlYU2Q=", "name"=>"Kyle Rau", "security_code_check"=>true, "created"=>"2017-07-13T11:11:36Z"}, "customer"=>"cust_test_10001", "ip"=>nil, "dispute"=>nil, "created"=>"2017-07-13T11:11:39Z"}, @options={}, @expanded_attributes={}>

Release an authorized charge

> omise_charge = Omise::Charge.retrieve('chrg_test_10001', key: SECRET_KEY)

> omise_charge.reverse(key: SECRET_KEY)
=> #<Omise::Charge:0x007f9cbaea9b48 @attributes={"object"=>"charge", "id"=>"chrg_test_10001", "livemode"=>false, "location"=>"/charges/chrg_test_10001", "amount"=>1000, "currency"=>"thb", "description"=>nil, "metadata"=>{}, "status"=>"reversed", "capture"=>false, "authorized"=>true, "reversed"=>true, "paid"=>false, "transaction"=>nil, "source_of_fund"=>"card", "refunded"=>0, "refunds"=>{"object"=>"list", "from"=>"1970-01-01T00:00:00Z", "to"=>"2017-07-13T13:01:30Z", "offset"=>0, "limit"=>20, "total"=>0, "order"=>nil, "location"=>"/charges/chrg_test_10001/refunds", "data"=>[]}, "return_uri"=>nil, "offsite"=>nil, "offline"=>nil, "reference"=>nil, "authorize_uri"=>nil, "failure_code"=>nil, "failure_message"=>nil, "card"=>{"object"=>"card", "id"=>"card_test_10001", "livemode"=>false, "location"=>"/customers/cust_test_10001/cards/card_test_10001", "country"=>"us", "city"=>nil, "postal_code"=>nil, "financing"=>"", "bank"=>"JPMORGAN CHASE BANK, N.A.", "last_digits"=>"1111", "brand"=>"Visa", "expiration_month"=>12, "expiration_year"=>2017, "fingerprint"=>"8VYaz0OJ7Lql+ddUCnHhWOqftGdyBX5FyUqSjAlYU2Q=", "name"=>"Arthur Cheng", "security_code_check"=>true, "created"=>"2017-07-13T13:00:53Z"}, "customer"=>"cust_test_10001", "ip"=>nil, "dispute"=>nil, "created"=>"2017-07-13T13:01:06Z"}, @options={}, @expanded_attributes={}>

Refund a captured charge

> omise_charge = Omise::Charge.retrieve('chrg_test_10001', key: SECRET_KEY)

> omise_charge.refunds.create(amount: 500, key: SECRET_KEY)
=> #<Omise::Refund:0x007fe1d3f14048 @attributes={"object"=>"refund", "id"=>"rfnd_test_10001", "location"=>"/charges/chrg_test_10001/refunds/rfnd_test_10001", "amount"=>500, "currency"=>"thb", "voided"=>false, "charge"=>"chrg_test_10001", "transaction"=>"trxn_test_10001", "created"=>"2017-07-13T13:16:26Z"}, @options={}, @expanded_attributes={}>

Back to top

5 Recipients API

Documentation: https://www.omise.co/recipients-api

5.1 Create a recipient

Omise.secret_api_key = 'sk_test_10001'

api_params = { name: 'Anchan Vegetarian Restaurant',
               email: '[email protected]',
               description: 'People typically spend 45 min to 1.5 hr here.',
               type: 'corporation',
               tax_id: '123456789',
               bank_account: {
                 brand: 'bbl',
                 number: '1234567890',
                 name: 'Anne Sarvis' } }

Omise::Recipient.create(api_params)
=> #<Omise::Recipient:0x007fc3c8a71b68 @attributes={"object"=>"recipient", "id"=>"recp_test_58zwwjh8e0tzhwtf4j3", "livemode"=>false, "location"=>"/recipients/recp_test_58zwwjh8e0tzhwtf4j3", "verified"=>false, "active"=>false, "name"=>"Anchan Vegetarian Restaurant", "email"=>"[email protected]", "description"=>"People typically spend 45 min to 1.5 hr here.", "type"=>"corporation", "tax_id"=>"123456789", "bank_account"=>{"object"=>"bank_account", "brand"=>"bbl", "last_digits"=>"7890", "name"=>"Anne Sarvis", "created"=>"2017-08-17T10:28:08Z"}, "failure_code"=>nil, "created"=>"2017-08-17T10:28:08Z"}, @options={}, @expanded_attributes={}>

To create a Recipient on Omise 'Indonesia', valid bank brand is CENAIDJA.

To use a secret_key per request, you can pass it in API call as follows:

Omise::Recipient.create(api_params.merge(key: 'sk_test_10002'))

Back to File

Back to Top

5.2 Retrieve a recipient

recipient = ::Omise::Recipient.retrieve('sk_test_10001')

Back to File

Back to Top

5.3 Update a recipient

recipient.update(api_params)

Back to File

Back to Top

6 Transfers API

Documentation: https://www.omise.co/transfers-api

6.1 Create a transfer

Omise.secret_api_key = 'sk_test_100010001'

api_params = { amount: 100000, recipient: recipient.id }

Omise::Transfer.create(api_params)
=> #<Omise::Transfer:0x007fc73fe75370 @attributes={"object"=>"transfer", "id"=>"trsf_test_590by1wzyc97yg82bj4", "livemode"=>false, "location"=>"/transfers/trsf_test_590by1wzyc97yg82bj4", "recipient"=>"recp_test_58zwwjh8e0tzhwtf4j3", "bank_account"=>{"object"=>"bank_account", "brand"=>"bbl", "last_digits"=>"7890", "name"=>"Anne Sarviss", "created"=>"2017-08-17T10:58:10Z"}, "sent"=>false, "paid"=>false, "amount"=>100000, "currency"=>"thb", "fee"=>3000, "fail_fast"=>false, "failure_code"=>nil, "failure_message"=>nil, "transaction"=>nil, "created"=>"2017-08-18T12:06:27Z", "sent_at"=>nil, "paid_at"=>nil}, @options={}, @expanded_attributes={}>

To use a secret_key per request, you can pass it in API call as follows:

Omise::Transfer.create(api_params.merge(key: 'sk_test_100010002'))

Back to File

Back to Top

7 Webhooks

To add a webhook URL, on your dashboard, click on "Webhooks". You can specify HTTPS URL for POST requests containing information about any transaction change on Omise.

Params for a sample webhook request look like below:

params
=> {"object"=>"event", "id"=>"evnt_test_58zwzhu9uudxcu92kr1", "livemode"=>false, "location"=>"/events/evnt_test_58zwzhu9uudxcu92kr1", "key"=>"recipient.verify", "created"=>"2017-08-17T17:36:32+07:00", "data"=>{"object"=>"recipient", "id"=>"recp_test_58zwwjh8e0tzhwtf4j3", "livemode"=>false, "location"=>"/recipients/recp_test_58zwwjh8e0tzhwtf4j3", "verified"=>true, "active"=>false, "name"=>"Anchan Vegetarian Restaurant", "email"=>"[email protected]", "description"=>"People typically spend 45 min to 1.5 hr here.", "type"=>"corporation", "tax_id"=>"123456789", "bank_account"=>{"object"=>"bank_account", "brand"=>"bbl", "last_digits"=>"7890", "name"=>"Anne Sarvis", "created"=>"2017-08-17T17:28:08+07:00"}, "failure_code"=>nil, "created"=>"2017-08-17T17:28:08+07:00"}, "action"=>"updated", "controller"=>"table_solution/omise_managed_accounts", "omise_managed_account"=>{"object"=>"event", "id"=>"evnt_test_58zwzhu9uudxcu92kr1", "livemode"=>false, "location"=>"/events/evnt_test_58zwzhu9uudxcu92kr1", "key"=>"recipient.verify", "created"=>"2017-08-17T17:36:32+07:00", "data"=>{"object"=>"recipient", "id"=>"recp_test_58zwwjh8e0tzhwtf4j3", "livemode"=>false, "location"=>"/recipients/recp_test_58zwwjh8e0tzhwtf4j3", "verified"=>true, "active"=>false, "name"=>"Anchan Vegetarian Restaurant", "email"=>"[email protected]", "description"=>"People typically spend 45 min to 1.5 hr here.", "type"=>"corporation", "tax_id"=>"123456789", "bank_account"=>{"object"=>"bank_account", "brand"=>"bbl", "last_digits"=>"7890", "name"=>"Anne Sarvis", "created"=>"2017-08-17T17:28:08+07:00"}, "failure_code"=>nil, "created"=>"2017-08-17T17:28:08+07:00"}}}

Back to File

Back to Top

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment