Skip to content

Instantly share code, notes, and snippets.

@jagdeepsingh
Last active June 20, 2022 08:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jagdeepsingh/e6fa5ff6d611c961e6ad7965b710b393 to your computer and use it in GitHub Desktop.
Save jagdeepsingh/e6fa5ff6d611c961e6ad7965b710b393 to your computer and use it in GitHub Desktop.
GMO Payment Gateway integration with Rails including Credit Card tokenization and setting up Managed Accounts through API

Home: https://www.gmo-pg.com/en/

Contents:

1 Register your company

To start accepting payments in test environment, you will need to register your company with GMO.

If the information given in the form is correct, then you will receive an email to confirm the registration.

After confirmation, you will get another email with urls, usernames and passwords for Site and Shop management screens.

Sample url for Site Management Screen - https://kt01.mul-pay.jp/path/to/site/

Under Site management -> Site information, you will find the Site ID and Password.

site:
  id: tsite00000001
  password: abcd1234

For Shop details, you can go to Site management -> Shop information and search for the shop you entered while registering on GMO.

Then clicking on the search result, you can access Shop ID and Password under Shop management -> Shop information.

shop:
  id: tshop00000002
  password: abcd0001

2 Install gem

We are using gem gmo to access the GMO Payment Gateway API.

# Gemfile
gem 'gmo', github: 't-k/gmo-payment-ruby'

Run bundle install to install it.

3 Generate token

Load the javascript based on your environnemt from following URLs (updated here by @playlistduong):

Environment JavaScript URL
Sandbox https://stg.static.mul-pay.jp/ext/js/token.js
Live https://static.mul-pay.jp/ext/js/token.js

Use Shop ID generated above to initialize the javascript library.

Multipayment.init(SHOP_ID);
Multipayment.getToken({
  holdername: 'Abby Yarbro',
  cardno: '4111111111111111',           // card number without spaces
  expire: '209912',                     // expiry in format 'YYYYMM'
  securitycode: '123'
}, 'gmoResponseHandler');               // callback function should be a string only

function gmoResponseHandler(response) {
  if(repsonse.resultCode == '000') {
    token = response.tokenObject.token;
    // use this token instead of card details to create transactions
  } else {
    // Failed to create token for the card
  }
}

4 Managed accounts

gmo = GMO::Payment::RemittanceAPI.new(shop_id: <Shop ID>,
                                      shop_pass: <Shop PASS>,
                                      host: 'test-remittance.gmopg.jp') # Sandbox mode

4.1 Create account

options = { bank_id: 'bank00001',
            bank_code: '0001',
            branch_code: '813',
            account_type: :normal,
            account_name: 'Jagdeep Singh',
            account_number: '0012345' }

gmo.create_account(options)  # => {"Bank_ID"=>"bank00001", "Method"=>"1"}

You can get the correct combinations of Bank Code and Branch Code from below links:

account_type can be set to any one of the below:

  • :normal
  • :current
  • :savings

Additional options that you can pass to create_account method are:

  • free Use it to store some metadata on the API
  • branch_code_jp e.g. MHCBJPJT
  • account_number_jp e.g. 01234567

4.2 Retrieve account

response = gmo.search_account(bank_id: 'bank12345')     # => {"Bank_ID"=>"bank12345", "Bank_Name"=>"みずほ銀行",
                                                        #     "Bank_Code"=>"0001", "Branch_Name"=>"札幌支店",
                                                        #     "Branch_Code"=>"813", "Account_Type"=>"1",
                                                        #     "Account_Number"=>"0012345", "Account_Name"=>"Jagdeep Singh",
                                                        #     "Free"=>"", "Branch_Code_Jpbank"=>"", "Account_Number_Jpbank"=>""}

4.3 Update account

options = { bank_id: 'bank00001',
            bank_code: '0001',
            branch_code: '813',
            account_type: :normal,
            account_name: 'Jagdeep Singh',
            account_number: '0012345' }

gmo.update_account(options)    # => {"Bank_ID"=>"bank00001", "Method"=>"2"}

4.4 Delete account

options = { bank_id: 'bank00001' }
gmo.delete_account(options)     # => {"Bank_ID"=>"bank00001", "Method"=>"3"}

4.5 Create deposit

options = { bank_id: 'bank00000',
            deposit_id: 'dep00000',
            amount: '1000' }

gmo.create_deposit(options)             # => {"Deposit_ID"=>"dep00000", "Bank_ID"=>"bank00000",
                                        #     "Method"=>"1", "Amount"=>"1000", "Bank_Fee"=>"27"}

4.6 Retrieve deposit

gmo.search_deposit(deposit_id: 'dep00000')     # => {"Deposit_ID"=>"dep00000", "Bank_ID"=>"bank163144",
                                               #     "Bank_Name"=>"みずほ銀行", "Bank_Code"=>"0001", "Branch_Name"=>"札幌支店",
                                               #     "Branch_Code"=>"813", "Account_Type"=>"1", "Account_Number"=>"0012345",
                                               #     "Account_Name"=>"Jagdeep Singh", "Free"=>"", "Amount"=>"1000",
                                               #     "Bank_Fee"=>"270", "Result"=>"0", "Branch_Code_Jpbank"=>"",
                                               #     "Account_Number_Jpbank"=>"", "Deposit_Date"=>"", "Result_Detail"=>""}

4.7 Cancel deposit

options = { bank_id: 'bank00000', deposit_id: 'dep00000' }
gmo.cancel_deposit(options)                     # => {"Deposit_ID"=>"dep00000", "Bank_ID"=>"bank00000", "Method"=>"2"}

4.8 Search balance

gmo.search_balance    # => {"Shop_ID"=>"rshop00000071", "Balance"=>"9818965", "Balance_Forecast"=>"9818965"}

4.9 Create mail deposit

options = { deposit_id: 'dep00001',
            deposit_email: 'jagdeepsingh.125k@gmail.com',
            amount: 1000,
            deposit_account_name: 'Jagdeep Singh',
            expire: 5,
            deposit_shop_email: 'foo@bar.com' }

gmo.create_mail_deposit(options)         # => {"Deposit_ID"=>"dep00001", "Method"=>"1", "Amount"=>"1000", "Expire"=>"20210503"}

options[:expire] represents number of days in advance to allow registration, from 1 to 30.

4.10 Retrieve mail deposit

gmo.search_mail_deposit(deposit_id: 'dep00001')     # => {"Deposit_ID"=>"dep00001", "Mail_Address"=>"jagdeepsingh.125k@gmail.com",
                                                    #     "Shop_Mail_Address"=>"foo@bar.com", "Account_Name"=>"Jagdeep Singh",
                                                    #     "Amount"=>"1000", "Expire"=>"20210503", "Status"=>"0"}

4.11 Cancel mail deposit

options = { deposit_id: 'dep00001' }
gmo.cancel_mail_deposit(options)         # => {"Deposit_ID"=>"dep00001", "Method"=>"2"}

5 Make transactions

Contents:

5.1 ShopAndSiteAPI

gmo_shop_site = GMO::Payment::ShopAndSiteAPI.new(host: 'p01.mul-pay.jp',   # live mode
                                                 site_id: SITE_ID,
                                                 site_pass: SITE_PASSWORD,
                                                 shop_id: SHOP_ID,
                                                 shop_pass: SHOP_PASSWORD)
=> #<GMO::Payment::ShopAndSiteAPI:0x007f8a67976488 @shop_id=SHOP_ID, @shop_pass=SHOP_PASSWORD, @site_id=SITE_ID, @site_pass=SITE_PASSWORD, @host="p01.mul-pay.jp">

For sandbox mode, use host kt01.mul-pay.jp.

5.1.1 ExecTranBrandtoken.idPass

gmo_shop_site.exec_tran_brandtoken(order_id: 'ord10001',
                                   access_id: '139f8ec33axxxxxxxxx7c52ce4473d',
                                   access_pass: '2689b204d2c1xxxxxxxxxx269fa7e744',
                                   token_type: :apple_pay,
                                   token: <Base64 encoded payment data>,
                                   member_id: 'mem10001')
=> {"Status"=>"CAPTURE", "OrderID"=>"ord10001", "Forward"=>"2a99663", "Approve"=>"5487394", "TranID"=>"1707281634111111111111771216", "TranDate"=>"20210728163453", "ClientField1"=>"", "ClientField2"=>"", "ClientField3"=>""}

Maximum allowed length of order_id is 27 characters.

5.1.2 TradedBrandtoken.idPass

gmo_shop_site.trade_brandtoken(member_id: 'mem10001', order_id: 'ord10001')
=> {"TokenSeq"=>"0", "CardNoToken"=>"*************111", "Forward"=>"2a99663"}

5.2 SiteAPI

gmo_site = GMO::Payment::SiteAPI.new(host: 'p01.mul-pay.jp', site_id: SITE_ID, site_pass: SITE_PASSWORD)
=> #<GMO::Payment::SiteAPI:0x007f8a6af80448 @site_id=SITE_ID, @site_pass=SITE_PASSWORD, @host="p01.mul-pay.jp">

For sandbox mode, use host kt01.mul-pay.jp.

5.2.1 SaveMember.idPass

gmo_site.save_member(member_id: 'mem10001')
=> {"MemberID"=>"mem10001"}

5.2.2 SearchBrandtoken.idPass

gmo_site.search_brandtoken(member_id: '598066176xxxxxxxx300020b', seq_mode: 0)
=> {"TokenSeq"=>"0", "DefaultFlag"=>"0", "CardName"=>"", "CardNoToken"=>"*************111", "Expire"=>"2212", "HolderName"=>"", "DeleteFlag"=>"0"}

5.2.3 DeleteBrandtoken.idPass

gmo_site.delete_brandtoken(member_id: '598066176xxxxxxxx300020b', seq_mode: 0, token_seq: 0)
=> {"TokenSeq"=>"0"}

5.3 ShopAPI

gmo_shop = GMO::Payment::ShopAPI.new(host: 'p01.mul-pay.jp', shop_id: SHOP_ID, shop_pass: SHOP_PASSWORD)
=> #<GMO::Payment::ShopAPI:0x007fef42e2e350 @shop_id=SHOP_ID, @shop_pass=SHOP_PASSWORD, @host="p01.mul-pay.jp"> 

For sandbox mode, use host kt01.mul-pay.jp.

5.3.1 EntryTranBrandtoken.idPass

entry_tran_response = gmo_shop.entry_tran_brandtoken(order_id: 'ord12345',
                                                     job_cd: 'AUTH',
                                                     item_code: '1000001',
                                                     tax: '0001001',
                                                     amount: 100)
=> {"AccessID"=>"xxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxx"}

5.3.2 ExecTranBrandtoken.idPass

gmo_shop.exec_tran_brandtoken(order_id: 'ord10001',
                              access_id: entry_tran_response['AccessID'],
                              access_pass: entry_tran_response['AccessPass'],
                              token_type: :apple_pay,
                              token: <Base64 encoded payment data>,
                              seq_mode: '1',
                              token_seq: 1001,
                              client_field_1: 'Custom field value 1',
                              client_field_2: 'Custom field value 2',
                              client_field_3: 'Custom field value 3')
=> {"Status"=>"AUTH", "OrderID"=>"ord10001", "Forward"=>"2a99663", "Approve"=>"5487394", "TranID"=>"1707281634111111111111771216", "TranDate"=>"20210728163453", "ClientField1"=>"Custom field value 1", "ClientField2"=>"Custom field value 2", "ClientField3"=>"Custom field value 3"}

5.3.3 SalesTranBrandtoken.idPass

gmo_shop.sales_tran_brandtoken(access_id: entry_tran_response['AccessID'],
                               access_pass: entry_tran_response['AccessPass'],
                               order_id: 'ord10001',
                               amount: 1000,
                               tax: '0001001')
=> {"AccessID"=>"xxxxxxxxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxxxxxxxx", "Status"=>"SALES", "Forward"=>"2a99663", "Approve"=>"5537883", "TranID"=>"1707311620111111111111771220", "TranDate"=>"20210731162256"}

5.3.4 ChangeTranBrandtoken.idPass

gmo_shop.change_tran_brandtoken(access_id: entry_tran_response['AccessID'],
                                access_pass: entry_tran_response['AccessPass'],
                                order_id: 'ord10001',
                                job_cd: 'CAPTURE',
                                amount: 2000)
=> {"AccessID"=>"xxxxxxxxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxxxxxxxx", "Status"=>"CAPTURE", "Forward"=>"2a99663", "Approve"=>"5538477", "TranID"=>"1707311633111111111111771224", "TranDate"=>"20210731163343"}

5.3.5 VoidTranBrandtoken.idPass

gmo_shop.void_tran_brandtoken(access_id: entry_tran_response['AccessID'],
                              access_pass: entry_tran_response['AccessPass'],
                              order_id: 'ord10001')
=> {"AccessID"=>"xxxxxxxxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxxxxxxxx", "Status"=>"VOID", "Forward"=>"2a99663", "Approve"=>"5537590", "TranID"=>"1707311610111111111111771219", "TranDate"=>"20210731161007"}

5.3.6 RefundTranBrandtoken.idPass

gmo_shop.refund_tran_brandtoken(access_id: entry_tran_response['AccessID'],
                                access_pass: entry_tran_response['AccessPass'],
                                order_id: 'ord10001',
                                amount: 1000,
                                tax: '0001001')
=> {"AccessID"=>"xxxxxxxxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxxxxxxxx", "Status"=>"RETURN", "Forward"=>"2a99663", "Approve"=>"5537883", "TranID"=>"1707311620111111111111771220", "TranDate"=>"20210731162256"}

5.3.7 SearchTradeMulti.idPass

gmo_shop.search_trade_multi(order_id: '59806617cxxxxxxxxx300020b', pay_type: 27)
=> {"OrderID"=>"59806617cxxxxxxxxx300020b", "Status"=>"CAPTURE", "ProcessDate"=>"20210801202929", "JobCd"=>"CAPTURE", "AccessID"=>"xxxxxxxxxxxxxxxxxxx", "AccessPass"=>"xxxxxxxxxxxxxxxxxxx", "ItemCode"=>"0000990", "Amount"=>"557", "Tax"=>"0", "SiteID"=>"", "MemberID"=>"", "CardNoToken"=>"************1111", "Expire"=>"2212", "Method"=>"1", "PayTimes"=>"", "Forward"=>"2a99663", "TranID"=>"1708012029111111111111771228", "Approve"=>"5689128", "ClientField1"=>"", "ClientField2"=>"", "ClientField3"=>"", "PayType"=>"27"}

Back to Top

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