Contents:
-
-
Save deivisonarthur/f91a95888ab089699e283653917cf7f6 to your computer and use it in GitHub Desktop.
Apple provides a set of guidelines for businesses that wish to incorporate Apple Pay into their websites. As a merchant, you must follow all of them to be eligible for using Apple Pay.
Contents:
- Register a Merchant ID
- Generate Payment Processing Certificate
- Register and verify website domain
- Generate Merchant Identity Certificate
You, as a merchant, will need an Apple Developer Account which you can setup on their Developer Console.
Log into your developer account and follow steps below to register a Merchant Identifier for your business:
- Go to Certificates, Identifiers & Profiles.
- Select Identifiers > Merchant IDs.
- Register a Merchant ID.
- Go to Certificates, Identifiers & Profiles.
- Select Identifiers > Merchant IDs.
- Select the Merchant ID you created and click Edit.
- In the Payment Processing Certificate section, click Create Certificate.
- Select if your payments will be processed exclusively in China and click "Continue".
-
Either Obtain a CSR file from your Payment Provider OR follow below steps to create a CSR file:
- In the Applications folder on your Mac, open Utilities and launch Keychain Access.
- In Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
- In the Certificate information window, enter the following:
- Email address
- Common Name for your key e.g. JD_TD_APPLE_PAY_PAYMENT_DEV_KEY
- Leave CA Email Address blank
- In the Request is group, select Saved to disk option.
- Select Let me specify key pair information.
- Click Continue and save the file at desired location.
- Set the Key Pair Information to the following:
- Algorithm: ECC
- Key Size: 256 bits
- Click Continue. Your certificate is generated.
-
Under Generate your certificate, click Choose File, select your CSR file, and click Continue.
- Download the certificate by clicking Download, and click Done. Certificate will be downloaded as apple_pay.cer.
- Follow guide to convert this ".cer" file to ".pem" file.
You will also need to register the domain where your application runs. It can be done as follows:
- Go to Certificates, Identifiers & Profiles.
- Select Identifiers > Merchant IDs.
- Select the Merchant ID from the list and click Edit.
- In Apple Pay on Web > Merchant Domains section, click on Add Domain button.
- Enter your fully qualified domain name. You can use ngrok to get a domain for localhost.
- On clicking Continue, you will be given a file to download.
On clicking Download, a file named apple-developer-merchantid-domain-association will be downloaded on your system.
Now, you need to host the file at location specified by Apple e.g. https://abcd1234.ngrok.io/.well-known/apple-developer-merchantid-domain-association. If you are using Ruby on Rails, you can do it as follows:
Put the downloaded file at path public/apple-developer-merchantid-domain-association.
# config/routes.rb
match '/.well-known/apple-developer-merchantid-domain-association',
to: 'apple_pay_merchants#domain_association'
# app/controllers/apple_pay_merchants_controller.rb
class ApplePayMerchantsController < ApplicationController
layout false
def domain_association
render file: 'public/apple-developer-merchantid-domain-association'
end
end
- Click on Verify button. Apple will ping the verification URL and if verification succeeds, the site returns to the iOS Merchant ID Settings page and Status will be set to Verified.
A Merchant Identity Certificate is needed to create a session with Apple.
- Go to Certificates, Identifiers & Profiles.
- Select Identifiers > Merchant IDs.
- Select the Merchant ID from the list and click Edit.
- In Apple Pay on Web > Merchant Identity Certificate section, click on Create Certificate button.
- Follow below steps to create a CSR file:
- In the Applications folder on your Mac, open Utilities and launch Keychain Access.
- In Keychain Access drop down menu, select Keychain Access > Certificate Assistant > Request a Certificate from a Certificate Authority.
- In the Certificate information window, enter the following:
- Email address
- Common Name for your key e.g. JD_TD_APPLE_PAY_MERCHANT_DEV_KEY
- Leave CA Email Address blank
- In the Request is group, select Saved to disk option.
- Do NOT select Let me specify key pair information.
- Click Continue and save the file at desired location.
- In Upload CSR file, click on Choose File and upload the CSR file generated in previous step. Click Continue.
- Download the generated Merchant Identity Certificate. Certificate will be named merchant_id.cer.
- Follow guide to convert this ".cer" file to ".pem" file.
You will need an iPhone that supports payments through Apple Pay. Complete list can be found here.
- Setup your finger print on your iPhone to make easy payments by just touching the home button. (Optional)
- Set up a Sandbox tester account on iTunes Connect.
- Sign in to iCloud on iPhone using tester account credentials.
- In iPhone > Settings > General > Language & Region, set region to one of the supported countries. Sandbox testing is supported only in these countries.
- In Wallet app on iPhone:
Your card will be added to Wallet now.
All test credit cards are available here.
- Select the card just added, click on "i" icon at the bottom, and enter Info > Billing Address for the card.
- In iPhone > Settings > Wallet & Apple Pay, set Default Card, Shipping Address, Email, and Phone.
- Setup your finger print on your iPhone to make easy payments by just touching the home button. (Optional)
- Sign in to iCloud on iPhone with your actual account.
- In iPhone > Settings > General > Language & Region, select your region.
- Add a credit card by scanning it or entering the card details manually.
- Select the card just added, click on "i" icon at the bottom, and enter Info > Billing Address for the card.
- In iPhone > Settings > Wallet & Apple Pay, set Default Card, Shipping Address, Email, and Phone.
In your iPhone, open Safari and run your application on HTTPS. You should see a working "Apple Pay" button there. Click the button and complete payment through touch ID or passcode.
Below is the sample Apple Pay JSON response:
payment = {"token"=>{"paymentData"=>{"version"=>"EC_v1", "data"=>"VsVvw2VCOaMa11WYJthb/MpAifih9wk2fqPU6FxJRrrCainBOPKjtW4mIBpnK0U/3BH+B3CA/j8yyoCuBUj900JyhyhGnyHP0vkz5iEO1rxEnjviJUkDktox8V8S9tOspjKssQ7yr6RlcjJA5P4Bj6GMgE+l+okFaKD1NRquMpRvi1MoplxYeX7KHDKsGQyRSgtY5zc/yvE3WHltcBnNpZlgJ995ACyuXAkcll75TGF+Qn+TY/9E//4QizZ+cRVjRYMRq19rWhtp2gW6stRuXy75SWefMwyLxl6tZaum2CGvQrijRfzzA5JYQr+vTEuMmr5mhm7AIIwnwapV272QRIYSOOI1L7c09xdTwKrDm8HbD+S3jo3TFgPktA64e9RtuEm1ream6BQM+5mP", "signature"=>"MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIID5jCCA4ugAwIBAgIIaGD2mdnMpw8wCgYIKoZIzj0EAwIwejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE2MDYwMzE4MTY0MFoXDTIxMDYwMjE4MTY0MFowYjEoMCYGA1UEAwwfZWNjLXNtcC1icm9rZXItc2lnbl9VQzQtU0FOREJPWDEUMBIGA1UECwwLaU9TIFN5c3RlbXMxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgjD9q8Oc914gLFDZm0US5jfiqQHdbLPgsc1LUmeY+M9OvegaJajCHkwz3c6OKpbC9q+hkwNFxOh6RCbOlRsSlaOCAhEwggINMEUGCCsGAQUFBwEBBDkwNzA1BggrBgEFBQcwAYYpaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwNC1hcHBsZWFpY2EzMDIwHQYDVR0OBBYEFAIkMAua7u1GMZekplopnkJxghxFMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUI/JJxE+T5O8n5sT2KGw/orv9LkswggEdBgNVHSAEggEUMIIBEDCCAQwGCSqGSIb3Y2QFATCB/jCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjA2BggrBgEFBQcCARYqaHR0cDovL3d3dy5hcHBsZS5jb20vY2VydGlmaWNhdGVhdXRob3JpdHkvMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwuYXBwbGUuY29tL2FwcGxlYWljYTMuY3JsMA4GA1UdDwEB/wQEAwIHgDAPBgkqhkiG92NkBh0EAgUAMAoGCCqGSM49BAMCA0kAMEYCIQDaHGOui+X2T44R6GVpN7m2nEcr6T6sMjOhZ5NuSo1egwIhAL1a+/hp88DKJ0sv3eT3FxWcs71xmbLKD/QJ3mWagrJNMIIC7jCCAnWgAwIBAgIISW0vvzqY2pcwCgYIKoZIzj0EAwIwZzEbMBkGA1UEAwwSQXBwbGUgUm9vdCBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcNMTQwNTA2MjM0NjMwWhcNMjkwNTA2MjM0NjMwWjB6MS4wLAYDVQQDDCVBcHBsZSBBcHBsaWNhdGlvbiBJbnRlZ3JhdGlvbiBDQSAtIEczMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATwFxGEGddkhdUaXiWBB3bogKLv3nuuTeCN/EuT4TNW1WZbNa4i0Jd2DSJOe7oI/XYXzojLdrtmcL7I6CmE/1RFo4H3MIH0MEYGCCsGAQUFBwEBBDowODA2BggrBgEFBQcwAYYqaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwNC1hcHBsZXJvb3RjYWczMB0GA1UdDgQWBBQj8knET5Pk7yfmxPYobD+iu/0uSzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFLuw3qFYM4iapIqZ3r6966/ayySrMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuYXBwbGUuY29tL2FwcGxlcm9vdGNhZzMuY3JsMA4GA1UdDwEB/wQEAwIBBjAQBgoqhkiG92NkBgIOBAIFADAKBggqhkjOPQQDAgNnADBkAjA6z3KDURaZsYb7NcNWymK/9Bft2Q91TaKOvvGcgV5Ct4n4mPebWZ+Y1UENj53pwv4CMDIt1UQhsKMFd2xd8zg7kGf9F3wsIW2WT8ZyaYISb1T4en0bmcubCYkhYQaZDwmSHQAAMYIBjDCCAYgCAQEwgYYwejEuMCwGA1UEAwwlQXBwbGUgQXBwbGljYXRpb24gSW50ZWdyYXRpb24gQ0EgLSBHMzEmMCQGA1UECwwdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTAghoYPaZ2cynDzANBglghkgBZQMEAgEFAKCBlTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNzA3MjUxMDUzMjBaMCoGCSqGSIb3DQEJNDEdMBswDQYJYIZIAWUDBAIBBQChCgYIKoZIzj0EAwIwLwYJKoZIhvcNAQkEMSIEIFhMf21I/tT+w8OsCgUduPdLdok+dAfM8m8U4l7dyEttMAoGCCqGSM49BAMCBEcwRQIhAOBE8SqThI+9ECZSMbGtl2C3tAi/G84UbZWMLdFHVyn3AiBBYBcrTKfOinw4hqDDe9FD3HGlD0004rgx50gthVyLZwAAAAAAAA==", "header"=>{"ephemeralPublicKey"=>"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6jY12R9PoL7bzaC3/ibs6q6+g/cqjSkiO3GVFld2NVUA6kRlq0iJRT+XzfmGFvRs/G2qwgmWY8fKu7p6Ktgxug==", "publicKeyHash"=>"AJiEM3d+czut7s1t4QdtRBPjSOxw0D6iWSp1MUdXueM=", "transactionId"=>"f8f0c804922303decba1a8a4f7c503df1a6314e44e8db5ae7eb6b7fe0323513b"}}, "paymentMethod"=>{"displayName"=>"MasterCard 1471", "network"=>"MasterCard", "type"=>"debit"}, "transactionIdentifier"=>"F8F0C804922303DECBA1A8A4F7C503DF1A6314E44E8DB5AE7EB6B7FE0323513B"}}
We are using gala and aead for decrypting the JSON response returned by Apple Pay.
# Gemfile
gem 'gala', '~> 0.3.1'
gem 'aead', git: 'https://github.com/Shopify/aead.git', ref: '340e7718d8bd9c1fcf3c443e32f439436ea2b70d'
Run bundle install
.
Please see this if you face any errors installing above gems.
require 'gala'
payment_token = ::Gala::PaymentToken.new(payment['token']['paymentData'])
=> #<Gala::PaymentToken:0x007feb6c73f2d0 @version="EC_v1", @data="VsVvw2VCOaMa11WYJthb/MpAifih9wk2fqPU6FxJRrrCainBOPKjtW4mIBpnK0U/3BH+B3CA/j8yyoCuBUj900JyhyhGnyHP0vkz5iEO1rxEnjviJUkDktox8V8S9tOspjKssQ7yr6RlcjJA5P4Bj6GMgE+l+okFaKD1NRquMpRvi1MoplxYeX7KHDKsGQyRSgtY5zc/yvE3WHltcBnNpZlgJ995ACyuXAkcll75TGF+Qn+TY/9E//4QizZ+cRVjRYMRq19rWhtp2gW6stRuXy75SWefMwyLxl6tZaum2CGvQrijRfzzA5JYQr+vTEuMmr5mhm7AIIwnwapV272QRIYSOOI1L7c09xdTwKrDm8HbD+S3jo3TFgPktA64e9RtuEm1ream6BQM+5mP", @signature="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", @transaction_id="f8f0c804922303decba1a8a4f7c503df1a6314e44e8db5ae7eb6b7fe0323513b", @ephemeral_public_key="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6jY12R9PoL7bzaC3/ibs6q6+g/cqjSkiO3GVFld2NVUA6kRlq0iJRT+XzfmGFvRs/G2qwgmWY8fKu7p6Ktgxug==", @public_key_hash="AJiEM3d+czut7s1t4QdtRBPjSOxw0D6iWSp1MUdXueM=", @application_data=nil>
cert = Rails.root.join('path', 'to', 'apple_pay.cer').read
=> "0\x82\u0004t0\x82\u0004\u0019\xA0\u0003\u0002...\xB3\u000F\xF0\b\xAE;\xF1j\u000Fʴ\xC8@\xC7"
pem = Rails.root.join('path', 'to', 'payment_processing_certificate.key.pem').read
=> "Bag Attributes\n friendlyName: TODO_PAYMENT_CSR_0728\n localKeyID: 51 61 60 E5 2F 38 ... FB 6E A8 17 DC 4E \nKey Attributes: <No Attributes>\n-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEILXPhijAztJ0l4zleKgTy1fSh2undI60AEUKc...+ZwK4YlMSmRkQ9swCKyRdjAs3vU6AXC+F8bA==\n-----END EC PRIVATE KEY-----\n"
data = payment_token.decrypt(cert, pem)
=> "{\"applicationPrimaryAccountNumber\":\"5204242750270010\",\"applicationExpirationDate\":\"190731\",\"currencyCode\":\"392\",\"transactionAmount\":346,\"deviceManufacturerIdentifier\":\"050110030273\",\"paymentDataType\":\"3DSecure\",\"paymentData\":{\"onlinePaymentCryptogram\":\"AK5g1Zu5CPm7AAV8DSTlAoABFA==\"}}"
JSON.parse(data)
=> {"applicationPrimaryAccountNumber"=>"5204242750270010", "applicationExpirationDate"=>"190731", "currencyCode"=>"392", "transactionAmount"=>346, "deviceManufacturerIdentifier"=>"050110030273", "paymentDataType"=>"3DSecure", "paymentData"=>{"onlinePaymentCryptogram"=>"AK5g1Zu5CPm7AAV8DSTlAoABFA=="}}
# Gemfile
gem 'gmo', github: 'JagdeepSingh/gmo-payment-ruby', branch: 'add-brandtoken-methods'
Run bundle install
.
Build ShopAPI
instance.
gmo_shop = GMO::Payment::ShopAPI.new(host: 'p01.mul-pay.jp', shop_id: SHOP_ID, shop_pass: SHOP_PASSWORD)
For test environment, use host 'kt01.mul-pay.jp'.
entry_tran_response = gmo_shop.entry_tran_brandtoken(order_id: 'ord10001',
job_cd: 'CAPTURE',
amount: 1000)
=> {"AccessID"=>"139f8ec33a07c55f406937c52ce4473d", "AccessPass"=>"2689b204d2c17192fa35f9269fa7e744"}
Sample Apple Pay JSON response.
payment = {"token"=>{"paymentData"=>{"version"=>"EC_v1", "data"=>"VsVvw2VCOaMa11WYJthb/MpAifih9wk2fqPU6FxJRrrCainBOPKjtW4mIBpnK0U/3BH+B3CA/j8yyoCuBUj900JyhyhGnyHP0vkz5iEO1rxEnjviJUkDktox8V8S9tOspjKssQ7yr6RlcjJA5P4Bj6GMgE+l+okFaKD1NRquMpRvi1MoplxYeX7KHDKsGQyRSgtY5zc/yvE3WHltcBnNpZlgJ995ACyuXAkcll75TGF+Qn+TY/9E//4QizZ+cRVjRYMRq19rWhtp2gW6stRuXy75SWefMwyLxl6tZaum2CGvQrijRfzzA5JYQr+vTEuMmr5mhm7AIIwnwapV272QRIYSOOI1L7c09xdTwKrDm8HbD+S3jo3TFgPktA64e9RtuEm1ream6BQM+5mP", "signature"=>"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", "header"=>{"ephemeralPublicKey"=>"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6jY12R9PoL7bzaC3/ibs6q6+g/cqjSkiO3GVFld2NVUA6kRlq0iJRT+XzfmGFvRs/G2qwgmWY8fKu7p6Ktgxug==", "publicKeyHash"=>"AJiEM3d+czut7s1t4QdtRBPjSOxw0D6iWSp1MUdXueM=", "transactionId"=>"f8f0c804922303decba1a8a4f7c503df1a6314e44e8db5ae7eb6b7fe0323513b"}}, "paymentMethod"=>{"displayName"=>"MasterCard 1471", "network"=>"MasterCard", "type"=>"debit"}, "transactionIdentifier"=>"F8F0C804922303DECBA1A8A4F7C503DF1A6314E44E8DB5AE7EB6B7FE0323513B"}}
require 'base64'
payment_token = Base64.encode64(payment['token']['paymentData'].to_json)
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: payment_token)
=> {"Status"=>"CAPTURE", "OrderID"=>"597ae8c36120b23a3c00014e", "Forward"=>"2a99663", "Approve"=>"5487394", "TranID"=>"1707281634111111111111771216", "TranDate"=>"20170728163453", "ClientField1"=>"", "ClientField2"=>"", "ClientField3"=>""}
In test environment, use Base64 ecnoded version of below tokens instead of actual token returned by Apple:
# Settlement OK / MASTER brand
{"header"=>{"ephemeralPublicKey"=>"testPublicKey", "publicKeyHash"=>"testKeyHash", "transactionId"=>"testTransaction"}, "data"=>"eyJhcHBsaWNhdGlvblByaW1hcnlBY2NvdW50TnVtYmVyIjogIjUxMTExMTExMTExMTExMTEiLCAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLCAiY3VycmVuY3lDb2RlIjoiMzkyIiwgInRyYW5zYWN0aW9uQW1vdW50IjoiMTAwMCIsICJjYXJkaG9sZGVyTmFtZSI6ICIiLCAiZGV2aWNlTWFudWZhY3R1cmVySWRlbnRpZmllciI6ICIiLCAicGF5bWVudERhdGFUeXBlIjoiM0RTZWN1cmUiLCAicGF5bWVudERhdGEiOiB7ICAgICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwgICAgImVjaUluZGljYXRvciIgOiAiMDUiICB9fQo=", "signature"=>"testSignature", "version"=>"Mock"}
# Settlement OK / JCB brand
{"header"=>{"ephemeralPublicKey"=>"testPublicKey", "publicKeyHash"=>"testKeyHash", "transactionId"=>"testTransaction"}, "data"=>"ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiMzExMTExMTExMTExMTExMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K", "signature"=>"testSignature", "version"=>"Mock"}
# Settlement OK / AMEX brand
{"header"=>{"ephemeralPublicKey"=>"testPublicKey", "publicKeyHash"=>"testKeyHash", "transactionId"=>"testTransaction"}, "data"=>"ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiMzc1OTg3MDAwMDAwMDYyIiwKICJhcHBsaWNhdGlvbkV4cGlyYXRpb25EYXRlIjogIjIyMTIzMSIsCiAiY3VycmVuY3lDb2RlIjoiMzkyIiwKICJ0cmFuc2FjdGlvbkFtb3VudCI6IjEwMDAiLAogImNhcmRob2xkZXJOYW1lIjogIiIsCiAiZGV2aWNlTWFudWZhY3R1cmVySWRlbnRpZmllciI6ICIiLAogInBheW1lbnREYXRhVHlwZSI6IjNEU2VjdXJlIiwgCiAicGF5bWVudERhdGEiOiB7CiAgIm9ubGluZVBheW1lbnRDcnlwdG9ncmFtIjogIkR1bW15Q0FWVkFBQUFBQUFBQUFBQUFBQUFBQUEiLAogICJlY2lJbmRpY2F0b3IiIDogIjA1IgogIH0KfQo=", "signature"=>"testSignature", "version"=>"Mock"}
# Settlement OK / VISA brand
{"header"=>{"ephemeralPublicKey"=>"testPublicKey", "publicKeyHash"=>"testKeyHash", "transactionId"=>"testTransaction"}, "data"=>"ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiNDExMTExMTExMTExMTExMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K", "signature"=>"testSignature", "version"=>"Mock"}
# Settlement NG / MASTER brand
{"header"=>{"ephemeralPublicKey"=>"testPublicKey", "publicKeyHash"=>"testKeyHash", "transactionId"=>"testTransaction"}, "data"=>"ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiNTk5OTAwMDAwMDAwMDAwMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K", "signature"=>"testSignature", "version"=>"Mock"}
Convert above tokens to JSON using to_json
and then call Base64.encode64
on them before passing in "ExecTranBrandtoken.idPass" request. All these tokens are available in a yml file here.
- Double-click on the ".cer" file to install in Keychain Access.
- Locate the certificate in Keychain Access. Right-click on it and select Export ....
- Select the location to save ".p12" file and click Continue.
- When prompted to set password, do NOT set any, and click Continue.
- Grant access and click Continue. You will have a ".p12" file now with the certificate and its secret key.
- Now, open the terminal and run
openssl pkcs12 -in path/to/p12/file -out Certificate.key.pem -nocerts -nodes
. When prompted to enter Import password, leave it blank. This will generate a Certificate.key.pem file. Check the name of output file carefully so that it does not over-write any existing certificate.
If you see below error while installing gala
and aead
:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
/Users/vinsol/.rvm/rubies/ruby-2.1.3/bin/ruby extconf.rb
checking for openssl/ssl.h... no
checking for SSLv23_method() in -lssl... yes
creating Makefile
make "DESTDIR=" clean
make "DESTDIR="
compiling aead.c
aead.c:2:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
^
1 error generated.
make: *** [aead.o] Error 1
make failed, exit code 2
Gem files will remain installed in /Users/vinsol/.rvm/gems/ruby-2.1.3/gems/aead-1.8.1 for inspection.
Results logged to /Users/vinsol/.rvm/gems/ruby-2.1.3/extensions/x86_64-darwin-14/2.1.0-static/aead-1.8.1/gem_make.out
An error occurred while installing aead (1.8.1), and Bundler cannot continue.
Make sure that `gem install aead -v '1.8.1'` succeeds before bundling.
Follow below steps:
$ brew update
$ brew install openssl
$ bundle config build.aead --with-cppflags=-I$(brew --prefix openssl)/include
$ bundle install
---
:applepay:
:token:
:mastercard:
header: &HEADER
ephemeralPublicKey: &TEST_PUBLIC_KEY testPublicKey
publicKeyHash: &TEST_KEY_HASH testKeyHash
transactionId: &TEST_TRANSACTION testTransaction
data: 'eyJhcHBsaWNhdGlvblByaW1hcnlBY2NvdW50TnVtYmVyIjogIjUxMTExMTExMTExMTExMTEiLCAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLCAiY3VycmVuY3lDb2RlIjoiMzkyIiwgInRyYW5zYWN0aW9uQW1vdW50IjoiMTAwMCIsICJjYXJkaG9sZGVyTmFtZSI6ICIiLCAiZGV2aWNlTWFudWZhY3R1cmVySWRlbnRpZmllciI6ICIiLCAicGF5bWVudERhdGFUeXBlIjoiM0RTZWN1cmUiLCAicGF5bWVudERhdGEiOiB7ICAgICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwgICAgImVjaUluZGljYXRvciIgOiAiMDUiICB9fQo='
signature: &TEST_SIGNATURE testSignature
version: &MOCK Mock
:jcb:
header: *HEADER
data: 'ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiMzExMTExMTExMTExMTExMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K'
signature: *TEST_SIGNATURE
version: *MOCK
:amex:
header: *HEADER
data: 'ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiMzc1OTg3MDAwMDAwMDYyIiwKICJhcHBsaWNhdGlvbkV4cGlyYXRpb25EYXRlIjogIjIyMTIzMSIsCiAiY3VycmVuY3lDb2RlIjoiMzkyIiwKICJ0cmFuc2FjdGlvbkFtb3VudCI6IjEwMDAiLAogImNhcmRob2xkZXJOYW1lIjogIiIsCiAiZGV2aWNlTWFudWZhY3R1cmVySWRlbnRpZmllciI6ICIiLAogInBheW1lbnREYXRhVHlwZSI6IjNEU2VjdXJlIiwgCiAicGF5bWVudERhdGEiOiB7CiAgIm9ubGluZVBheW1lbnRDcnlwdG9ncmFtIjogIkR1bW15Q0FWVkFBQUFBQUFBQUFBQUFBQUFBQUEiLAogICJlY2lJbmRpY2F0b3IiIDogIjA1IgogIH0KfQo='
signature: *TEST_SIGNATURE
version: *MOCK
:visa:
header: *HEADER
data: 'ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiNDExMTExMTExMTExMTExMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K'
signature: *TEST_SIGNATURE
version: *MOCK
:error:
:master:
header: *HEADER
data: 'ewogImFwcGxpY2F0aW9uUHJpbWFyeUFjY291bnROdW1iZXIiOiAiNTk5OTAwMDAwMDAwMDAwMSIsCiAiYXBwbGljYXRpb25FeHBpcmF0aW9uRGF0ZSI6ICIyMjEyMzEiLAogImN1cnJlbmN5Q29kZSI6IjM5MiIsCiAidHJhbnNhY3Rpb25BbW91bnQiOiIxMDAwIiwKICJjYXJkaG9sZGVyTmFtZSI6ICIiLAogImRldmljZU1hbnVmYWN0dXJlcklkZW50aWZpZXIiOiAiIiwKICJwYXltZW50RGF0YVR5cGUiOiIzRFNlY3VyZSIsIAogInBheW1lbnREYXRhIjogewogICJvbmxpbmVQYXltZW50Q3J5cHRvZ3JhbSI6ICJEdW1teUNBVlZBQUFBQUFBQUFBQUFBQUFBQUFBIiwKICAiZWNpSW5kaWNhdG9yIiA6ICIwNSIKICB9Cn0K'
signature: *TEST_SIGNATURE
version: *MOCK