Payabli

Integration Overview

There are multiple ways to incorporate the payment gateway within a website or mobile device. These options vary based upon ease of integration, required resources, features, and additional security.

Transaction Request APIs
Three-Step Redirect API
  • The Three Step Redirect is the preferred API for customized web-based payment processing. Using this integration method significantly reduces a merchant’s PCI footprint without sacrificing end-user look and feel. This method is required when using Verified by Visa/Mastercard SecureCode (Payer Authentication).

Direct Post API
  • The Direct Post method is the simplest integration method for both web-based and non web-based payment applications, however, merchants using this integration method should have passed a PCI vulnerability scan before use.

Collect.js
  • Collect.js provides access to a popup form which securely captures payment data and generates a “token”. The token is then used with the Direct Post API instead of raw credit card or bank account data. The popup form is technically a seperate page hosted by the gateway, so no payment information touches the merchant’s site. This allows merchants to minimize their PCI-compliance footprint, with minimal changes to the customer experience.

Collect Checkout
  • Collect Checkout is a hosted checkout page that can be integrated into most web-based payment workflows. The checkout page lives entirely on the gateway’s servers, ensuring that no payment data ever touches your environment.

Mobile SDK
  • The Mobile SDK supports iOS and Android based devices. These SDKs include a mobile card reader library which simplifies integrations for applications requiring encrypted mobile card readers. Additionally, an end-to-end encryption library is included, allowing merchants to send both swiped and keyed-in payment information without ever touching any sensitive data.

EMV Chip Card SDK
  • The EMV Chip Card SDK is a Windows-based software development kit that abstracts the complexities of interfacing directly with hardware terminals.

Transaction Retrieval API
Webhooks
  • Webhooks allow merchants to receive next-to-real-time notifications of events happening on their account. While the Query API lets integrators “pull” information from the gateway, webhooks “push” information to the integrator.

Query API
  • The Query API allows merchants to download a detailed stream of transaction data. This dataset can then be used to create in-house reports and analytics.

Turnkey Shopping Carts
QuickClick Shopping Cart
  • QuickClick is a great option for e-commerce merchants who do not have an IT team or developer on staff. A button-generator is included, which allows merchants to create website links to products and services without any previous development experience.

Third Party Shopping Carts
  • There are a number of third party shopping carts that have integrated to the payment gateway. This is the best option for merchants who need a full featured turn-key shopping cart out of the box.

Customer Vault Variables

Direct Post API

POST URL
POST URL: https://centavo.transactiongateway.com/api/transact.php
Add/Update Customer Record
Variables Description
customer_vault* Add/Update a secure customer vault record. Values: ‘add_customer’ or ‘update_customer’
customer_vault_id Specifies a customer vault id. If not set, the payment gateway will randomly generate a customer vault id.
billing_id Billing id to be assigned or updated. If none is provided, one will be created or the billing id with priority ‘1’ will be updated.
security_key* API Security Key assigned to a merchant account. New keys can be generated from the merchant control panel in Settings > Security Keys
payment_token The tokenized version of the customer’s card or check information. This will be generated by Collect.js and is usable only once.
googlepay_payment_data The encrypted token created when integration directly to the Google Pay SDK.
ccnumber** Credit card number.
ccexp** Credit card expiration.
Format: MMYY
checkname*** The name on the customer’s ACH account.
checkaba*** The customer’s bank routing number.
checkaccount*** The customer’s bank account number.
account_holder_type The customer’s ACH account entity.
Values: ‘personal’ or ‘business’
account_type The customer’s ACH account type.
Values: ‘checking’ or ‘savings’
sec_code ACH standard entry class codes.
Values: ‘PPD’, ‘WEB’, ‘TEL’, or ‘CCD’
currency Set transaction currency.
payment Set payment type to ACH or credit card.
Values: ‘creditcard’ or ‘check’
orderid Order id
order_description Order Description
Legacy variable includes: orderdescription
merchant_defined_field_# Can be set up in merchant control panel under ‘Settings’->’Merchant Defined Fields’. Format: merchant_defined_field_1=Value
first_name Cardholder’s first name.
Legacy variable includes: firstname
last_name Cardholder’s last name.
Legacy variable includes: lastname
address1 Card billing address.
city Card billing city
state Card billing state.
zip Card billing postal code.
country Card billing country code.
phone Billing phone number.
email Billing email address.
company Cardholder’s company.
address2 Card billing address, line 2.
fax Billing fax number.
shipping_id Shipping entry id. If none is provided, one will be created or the billing id with priority ‘1’ will be updated.
shipping_firstname Shipping first name.
shipping_lastname Shipping last name.
shipping_company Shipping company.
shipping_address1 Shipping address.
shipping_address2 Shipping address, line 2.
shipping_city Shipping city
shipping_state Shipping state.
shipping_zip Shipping postal code.
shipping_country Shipping country code.
shipping_phone Shipping phone number.
shipping_fax Shipping fax number.
shipping_email Shipping email address.
source_transaction_id Specifies a payment gateway transaction id in order to associate payment information with a Customer Vault record.
Always required
Required for credit card transactions
Required for ACH transactions

Customer Vault initiated Sale/Auth/Credit/Offline
Variable Description
security_key* API Security Key assigned to a merchant account. New keys can be generated from the merchant control panel in Settings > Security Keys
customer_vault_id* Specifies a customer vault id.
amount Total amount to be charged. For validate, the amount must be omitted or set to 0.00.
Format: x.xx
currency The transaction currency. Format: ISO 4217
processor_id If using Multiple MIDs, route to this processor (processor_id is obtained under Settings->Transaction Routing in the Control Panel).
descriptor Set payment descriptor on supported processors.
descriptor_phone Set payment descriptor phone on supported processors.
order_description Order description. Legacy variable includes: orderdescription
orderid Order ID
Stored Credentials (CIT/MIT)
initiated_by Who initiated the transaction.
Values: ‘customer’ or ‘merchant’
initial_transaction_id Original payment gateway transaction id.
stored_credential_indicator The indicator of the stored credential.
Values: ‘stored’ or ‘used’
Use ‘stored’ when processing the initial transaction in which you are storing a customer’s payment details (customer credentials) in the Customer Vault or other third-party payment storage system.
Use ‘used’ when processing a subsequent or follow-up transaction using the customer payment details (customer credentials) you have already stored to the Customer Vault or third-party payment storage method.
Always required

Delete Customer Record
Variable Description
customer_vault* Deletes a secure customer vault record.
Values: ‘delete_customer’
customer_vault_id* Specifies a customer vault id.
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
Always required

Notes:
  • If you do not pass a customer_vault_id, our system will randomly generate one. If you include a customer_id and customer_vault_id, they must match.
  • You can only pass Credit Card or Electronic Check transaction variables.


Methodology

Three-Step

Method Overview
  • Step One: Submit all transaction details to the Payment Gateway except the customer’s sensitive payment information. The Payment Gateway will return a variable form-url.

  • Step Two: Create an HTML form that collects the customer’s sensitive payment information and use the form-url that the Payment Gateway returns as the submit action in that form.

  • Step Three: Once the customer has been redirected, obtain the token-id and complete the transaction through an HTTPS POST including the token-id which abstracts the sensitive payment information that was collected directly by the Payment Gateway.

Detailed Explanation

To start step one, your payment application will submit a behind-the-scenes HTTPS direct POST that includes transaction variables, including an additional variable redirect-url, which is a URL that must exist on your web server that handles a future browser redirect. Sensitive payment information such as cc-number, cc-exp, and cvv cannot be submitted during step one. The Payment Gateway will generate and return the form-url variable containing a unique URL to be used in Step 2.

Next, during step two, you must develop an HTML form that collects at least the customer’s sensitive payment information such as cc-number, cc-exp, and cvv. You must use the form-url obtained in step one as the action in the HTML of your payment form. When the customer submits the form, the customer’s browser will transparently POST the contents of the payment form directly to the Payment Gateway. This methodology keeps your web server and payment application from seeing or transmitting any credit card data or other sensitive data. Once the Payment Gateway has collected the customer’s sensitive payment details, the customer’s browser will be instructed to return to the redirect-url on your web server. Furthermore, the Payment Gateway will generate and append a unique variable named token-id to the redirect-url in the GET query string. This token-id is an abstraction of the customer’s sensitive payment information that the Payment Gateway collected. Your redirect-url script must parse the token-id for use in step three.

To complete the transaction, you will submit another behind-the-scenes HTTPS direct POST including only the token-id and api-key. This token-id is used to “tie” together the initial customer information with the sensitive payment information that the payment gateway collected directly.




Testing Information

Three-Step

Transaction Testing Credentials

Transactions can be tested using one of two methods. First, transactions can be submitted to any merchant account that is in test mode. Keep in mind that if an account is in test mode, all valid credit cards will be approved but no charges will actually be processed.

The Payment Gateway demo account can also be used for testing at any time. Please use the following api-key for testing with this account:

api-key: 2F822Rw39fx762MaV7Yy86jXGTC7sCDy
Transaction POST URL

In step one and step three, transaction details should be POST’ed using XML to the following URL:

POST URL https://centavo.transactiongateway.com/api/v2/three-step
Test Data

Transactions can be submitted using the following information:

Visa: 4111111111111111
MasterCard: 5431111111111111
Discover: 6011601160116611
American Express: 341111111111111
Diner’s Club: 30205252489926
JCB: 3541963594572595
Maestro: 6799990100000000019
Credit Card Expiration: 10/25
account (ACH): 123123123
routing (ACH): 123123123
amount 1.00 (Amounts under 1.00 generate failure).
Triggering Errors in Test Mode
  • To cause a declined message, pass an amount less than 1.00.
  • To trigger a fatal error message, pass an invalid card number.
  • To simulate an AVS match, pass 888 in the address1 field, 77777 for zip.
  • To simulate a CVV match, pass 999 in the cvv field.

Appendix 1

Three-Step

AVS Response Codes
X Exact match, 9-character numeric ZIP
Y Exact match, 5-character numeric ZIP
D Exact match, 5-character numeric ZIP
M Exact match, 5-character numeric ZIP
2 Exact match, 5-character numeric ZIP, customer name
6 Exact match, 5-character numeric ZIP, customer name
A Address match only
B Address match only
3 Address, customer name match only
7 Address, customer name match only
W 9-character numeric ZIP match only
Z 5-character ZIP match only
P 5-character ZIP match only
L 5-character ZIP match only
1 5-character ZIP, customer name match only
5 5-character ZIP, customer name match only
N No address or ZIP match only
C No address or ZIP match only
4 No address or ZIP or customer name match only
8 No address or ZIP or customer name match only
U Address unavailable
G Non-U.S. issuer does not participate
I Non-U.S. issuer does not participate
R Issuer system unavailable
E Not a mail/phone order
S Service not supported
0 AVS not available
O AVS not available
B AVS not available

Appendix 2

Three-Step

CVV Response Codes
M CVV2/CVC2 match
N CVV2/CVC2 no match
P Not processed
S Merchant has indicated that CVV2/CVC2 is not present on card
U Issuer is not certified and/or has not provided Visa encryption keys

Appendix 3

Three-Step

Result Code Table
100 Transaction was approved.
200 Transaction was declined by processor.
201 Do not honor.
202 Insufficient funds.
203 Over limit.
204 Transaction not allowed.
220 Incorrect payment information.
221 No such card issuer.
222 No card number on file with issuer.
223 Expired card.
224 Invalid expiration date.
225 Invalid card security code.
226 Invalid PIN.
240 Call issuer for further information.
250 Pick up card.
251 Lost card.
252 Stolen card.
253 Fraudulent card.
260 Declined with further instructions available. (See response text)
261 Declined-Stop all recurring payments.
262 Declined-Stop this recurring program.
263 Declined-Update cardholder data available.
264 Declined-Retry in a few days.
300 Transaction was rejected by gateway.
400 Transaction error returned by processor.
410 Invalid merchant configuration.
411 Merchant account is inactive.
420 Communication error.
421 Communication error with issuer.
430 Duplicate transaction at processor.
440 Processor format error.
441 Invalid transaction information.
460 Processor feature not available.
461 Unsupported card type.

Step One

Three-Step: Transactions

Sale/Auth/Credit/Validate/Offline XML Request
XML Element Description
<sale|auth|credit|validate|offline> Type of transaction to perform.
api-key* api-key is obtained in the security keys section of the control panel settings.
redirect-url* A URL on your web server that the gateway will redirect your customer to after sensitive data collection.
amount* Total amount to be charged (For “validate” actions, amount must be 0.00 or omitted).
surcharge-amount Surcharge amount.
Format: x.xx
authorization-code** Specify authorization code. For use with “offline” action only.
ip-address Cardholder’s IP address.
Format: xxx.xxx.xxx.xxx
industry Specify industry classification of transaction.
Values: ‘ecommerce’, ‘moto’, or ‘retail’
billing-method Set additional billing indicators.
Values: ‘recurring’ or ‘installment’
billing-number Specify installment billing number, on supported processors. For use when “billing-method” is set to installment.
Values: 0-99
billing-total Specify installment billing total on supported processors. For use when “billing-method” is set to installment.
processor-id If using multiple processors, route to specified processor. Obtained under Settings->Transaction Routing in the merchant control panel.
sec-code ACH standard entry class codes.
Values: ‘PPD’, ‘WEB’, ‘TEL’, ‘CCD’, ‘POP’, or ‘ARC’
descriptor Set payment descriptor on supported processors.
descriptor-phone Set payment descriptor phone on supported processors.
descriptor-address Set payment descriptor address on supported processors.
descriptor-city Set payment descriptor city on supported processors.
descriptor-state Set payment descriptor state on supported processors.
descriptor-postal Set payment descriptor postal code on supported processors.
descriptor-country Set payment descriptor country on supported processors.
descriptor-mcc Set payment descriptor mcc on supported processors.
descriptor-merchant-id Set payment descriptor merchant id on supported processors.
descriptor-url Set payment descriptor url on supported processors.
currency Set transaction currency.
Format: ISO 4217
order-description Order description.
customer-id Customer identification.
customer-vault-id Load customer details from an existing customer vault record. If set, no payment information is required during step two.
merchant-receipt-email Send merchant receipt to email
customer-receipt Send receipt if billing email included.
Values: ‘true’ or ‘false’
merchant-defined-field-# Merchant specified custom fields.
Format: <merchant-defined-field-1>Value</merchant-defined-field-1>
tracking-number Shipping tracking number.
shipping-carrier Shipping carrier.
Values: ‘ups’, ‘fedex’, ‘dhl’, or ‘usps’
order-id*** Order id.
signature-image Cardholder signature image. For use with “sale” and “auth” actions only.
Format: base64 encoded raw PNG image. (16kiB maximum)
po-number*** Cardholder’s purchase order number.
tax-amount*** The sales tax included in the transaction amount associated with the purchase. Setting tax equal to ‘-1’ indicates an order that is exempt from sales tax.
Default: ‘0.00’
Format: x.xx
shipping-amount*** Total shipping amount.
ship-from-postal**** Postal/ZIP code of the address from where purchased goods are being shipped. Defaults to merchant profile postal code.
summary-commodity-code**** A code representing the type of commodity being purchased. The acquirer or processor will provide a list of current codes.
duty-amount Amount included in the transaction amount associated with the import of the purchased goods.
Default: ‘0.00’
discount-amount Amount included in the transaction amount of any discount applied to the complete order by the merchant.
Default: ‘0.00’
national-tax-amount The national tax amount included in the transaction amount.
Default: ‘0.00’
alternate-tax-amount Second tax amount included in the transaction amount in countries where more than one type of tax can be applied to the purchases.
Default: ‘0.00’
alternate-tax-id Tax identification number of the merchant that reported the alternate tax amount.
vat-tax-amount Contains the amount of any value added taxes which can be associated with the purchased item.
Default: ‘0.00’
vat-tax-rate Contains the tax rate used to calculate the sales tax amount appearing. Can contain up to 2 decimal places, ie 1% = 1.00.
Default: ‘0.00’
vat-invoice-reference-number Invoice number that is associated with the VAT invoice.
customer-vat-registration Value added tax registration number supplied by the cardholder.
merchant-vat-registration Government assigned tax identification number of the merchant from whom the goods or services were purchased.
order-date Purchase order date. Defaults to the date of the transaction.
Format: YYMMDD
skip-3ds Skip over 3DS authentication process for this specific transaction.
Values: “true” or “false”
cardholder-auth Set 3D Secure condition.
Values: ‘verified’ or ‘attempted’
eci E-commerce indicator.
Values: ‘0’, ‘1’, ‘2’, ‘5’, ‘6’, or ‘7’
cavv Cardholder authentication verification value.
Format: base64 encoded
xid Cardholder authentication transaction id.
Format: base64 encoded
three-ds-version 3DSecure version.
Examples: “1.0.2” or “2.0”
directory-server-id Directory Server Transaction ID. May be provided as part of 3DSecure 2.0 authentication.
Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
initiated-by Who initiated the transaction.
Values: ‘customer’ or ‘merchant’
initial-transaction-id Original payment gateway transaction id.
stored-credential-indicator The indicator of the stored credential.
Values: ‘stored’ or ‘used’
Use ‘stored’ when processing the initial transaction in which you are storing a customer’s payment details (customer credentials) in the Customer Vault or other third-party payment storage system.
Use ‘used’ when processing a subsequent or follow-up transaction using the customer payment details (customer credentials) you have already stored to the Customer Vault or third-party payment storage method.
dup-seconds Override duplicate transaction detection time in seconds.
avs-reject The transaction is rejected if the address verification result is a code in this list. Values are letters obtained under Settings->Address Verification in the control panel.
Format: x|x|x|x…
cvv-reject The transaction is rejected if the card ID verification result is a code in this list. Values are letters obtained under Settings->Card ID Verification in the control panel.
Format: x|x|x|x…
<billing> The customer’s billing information
billing-id Specify billing id. Recommended when using customer vault hybrid action. Will be ignored if no hybrid add/update-customer is done.
first-name Cardholder’s first name.
last-name Cardholder’s last name.
address1 Cardholder’s billing address.
city Card billing city.
state Card billing state/province.
Format: CC
postal Card billing postal code.
country Card billing country code.
Format: CC/ISO 3166
phone Billing phone number.
email Billing email address.
company Cardholder’s company.
address2 Card billing address, line 2.
fax Billing fax number.
account-type§ The customer’s ACH account type.
Values: ‘checking’ or ‘savings’
entity-type§ The customer’s ACH account entity.
Values: ‘personal’ or ‘business’
</billing>
<shipping> The customer’s shipping information.
shipping-id Specify shipping id. Recommended when using customer vault hybrid action. Will be ignored if no hybrid add/update-customer is done.
first-name Shipping first name.
last-name Shipping last name.
address1 Shipping billing address.
city Shipping city.
state Shipping state/province.
Format: CC
postal**** Shipping postal code.
country**** Shipping country code.
Format: CC/ISO 3166
phone Shipping phone number.
email Shipping email address.
company Shipping company.
address2 Shipping address, line 2.
fax Shipping fax number.
</shipping>
<product> Product line item detail. Multiple product elements are allowed.
product-code****¶ Merchant defined description code of the item being purchased.
description**** Description of the item(s) being supplied.
commodity-code**** International description code of the individual good or service being supplied. The acquirer or processor will provide a list of current codes.
unit-of-measure**** Code for units of measurement as used in international trade.
Default: ‘EACH’
unit-cost**** Unit cost of item purchased. May contain up to 4 decimal places.
quantity**** Quantity of the item(s) being purchased.
Default: ‘1’
total-amount**** Purchase amount associated with the item. Default to ‘unit-cost’ x ‘quantity’ rounded to the nearest penny.
tax-amount**** Amount of tax on specific item. Amount should not be included in item-total-amount.
Default: ‘0.00’
tax-rate**** Percentage representing the value-added tax applied. 1% = 1.00.
Default: ‘0.00’
discount-amount Discount amount which can have been applied by the merchant on the sale of the specific item. Amount should not be included in ‘item-total-amount’.
discount-rate Discount rate for the line item. 1% = 1.00.
Default: ‘0.00’
tax-type Type of value-added taxes that are being used.
alternate-tax-id Tax identification number of the merchant that reported the alternate tax amount.
</product>
<add-subscription> Perform a simultaneous ‘hybrid’ recurring action while processing a transaction.
start-date The first day that the customer will be charged. Format: YYYYMMDD
<plan>
plan-id The unique plan ID that references only this recurring plan.
payments The number of payments before the recurring plan is complete.
Note: Use ‘0’ for ‘until canceled’
amount The plan amount to be charged each billing cycle.
Format: x.xx
day-frequency How often, in days, to charge the customer. Cannot be set with ‘month-frequency’ or ‘day-of-month’.
month-frequency How often, in months, to charge the customer. Cannot be set with ‘day-frequency’. Must be set with ‘day-of-month’.
Values: 1 through 24
day-of-month The day that the customer will be charged. Cannot be set with ‘day-frequency’. Must be set with ‘month-frequency’.
Values: 1 through 31 – for months without 29, 30, or 31 days, the charge will be on the last day
</plan>
</add-subscription>
<add-customer|update-customer> Perform a simultaneous ‘hybrid’ customer vault action while processing a transaction. This tag can be blank if submitting an ‘add-customer’ without specifying a ‘customer-vault-id’.
customer-vault-id Specify customer vault id. If omitted, will be auto-generated and returned in response. Required for ‘update-customer’.
</add-customer|update-customer>
partial-payments Specify whether a partial amount or full amount of the transaction should be settled.
Format: ‘settle_partial’ or ‘payment_in_full’
partial-payment-id Specify a partial payment ID. Required to collect an additional amount associated with an existing Partial Payment Transaction. Do not use on initial transaction.
</sale|auth|credit|validate|offline>
Always required
Required for offline transactions
Required for Level 2 and Level 3 transactions
Required for Level 3 transactions
Required for 3D-Secure transactions
Required for Override transactions
Required for Partial Payment Transactions
Required for ACH transactions
Required for Line Item Reporting

Sale/Auth/Credit/Validate/Offline XML Response
XML Element Description
<response>
result 1=Approved
2=Declined
3=Error in transaction data or system error
result-text Textual response.
transaction-id Payment Gateway transaction id.
result-code Numeric mapping of processor responses (See Appendix 3).
form-url URL used as the action of the HTML form in step two.
</response>
step2
step3

Methodology

Direct Post API

Transactions

Steps:
1. The customer sends their payment information to the merchant’s web site.
2. The merchant web site posts the payment data to the Payment Gateway.
3. The Payment Gateway responds immediately with the results of the transactions.
4. The merchant web site displays the appropriate message to the customer.

The communication method used to send messages to the Payment Gateway’s server is the standard HTTP protocol over an SSL connection.

In the Direct Post method, the communications with the cardholder (Steps 1 and 4) are developed completely by the merchant and therefore are not defined by the Payment Gateway. Step 1 should simply collect the payment data from the cardholder and Step 4 should display the appropriate transaction receipt or declined message.

In Step 2, transaction details should be delivered to the Payment Gateway using the POST method with the appropriate variables defined below posted along with the request.

In Step 3, the transaction responses are returned in the body of the HTTP response in a query string name/value format delimited by ampersands. For example: variable1=value1&variable2=value2&variable3=value3

Customer Vault

The Customer Vault was designed specifically for businesses of any size to address concerns about handling customer payment information. Visa and MasterCard have instituted the Payment Card Industry (PCI) Data Security to protect cardholder data, wherever it resides, ensuring that members, merchants, and service providers maintain the highest information security standards.

These associations have also deemed that merchants will be held liable for any breach of cardholder data. This has become a major concern for merchants who handle credit card or electronic check payments. The Customer Vault is designed for these merchants who desire to avoid the tremendous costs and resources involved in becoming PCI compliant under these circumstances.

The Customer Vault does this by allowing merchants to transmit their payment information through a Secure Sockets Layer (SSL) connection for storage in our Level 1 PCI certified data facility. Once the customer record has been securely transmitted to the Customer Vault, the merchant can then initiate transactions remotely without having to access cardholder information directly. This process is accomplished without the merchant storing the customer’s payment information in their local database or payment application.

Transaction Types

Direct Post API

Sale (sale)

Transaction sales are submitted and immediately flagged for settlement.

Authorization (auth)

Transaction authorizations are authorized immediately but are not flagged for settlement. These transactions must be flagged for settlement using the capture transaction type.

Capture (capture)

Transaction captures flag existing authorizations for settlement. Only authorizations can be captured. Captures can be submitted for an amount equal to or less than the original authorization.

Void (void)

Transaction voids will cancel an existing sale or captured authorization. In addition, non-captured authorizations can be voided to prevent any future capture. Voids can only occur if the transaction has not been settled.

Refund (refund)

Transaction refunds will reverse a previously settled or pending settlement transaction. If the transaction has not been settled, a transaction void can also reverse it.

Credit (credit)

Transaction credits apply an amount to the cardholder’s card that was not originally processed through the Gateway. In most situations credits are disabled as transaction refunds should be used instead.

Validate (validate)

This action is used for doing an “Account Verification” on the cardholder’s credit card without actually doing an authorization.

Update (update)

Transaction updates can be used to update previous transactions with specific order information, such as a tracking number and shipping carrier.

Appendix 1

Direct Post API

AVS Response Codes
X Exact match, 9-character numeric ZIP
Y Exact match, 5-character numeric ZIP
D Exact match, 5-character numeric ZIP
M Exact match, 5-character numeric ZIP
2 Exact match, 5-character numeric ZIP, customer name
6 Exact match, 5-character numeric ZIP, customer name
A Address match only
B Address match only
3 Address, customer name match only
7 Address, customer name match only
W 9-character numeric ZIP match only
Z 5-character ZIP match only
P 5-character ZIP match only
L 5-character ZIP match only
1 5-character ZIP, customer name match only
5 5-character ZIP, customer name match only
N No address or ZIP match only
C No address or ZIP match only
4 No address or ZIP or customer name match only
8 No address or ZIP or customer name match only
U Address unavailable
G Non-U.S. issuer does not participate
I Non-U.S. issuer does not participate
R Issuer system unavailable
E Not a mail/phone order
S Service not supported
0 AVS not available
O AVS not available
B AVS not available

Appendix 2

Direct Post API

CVV Response Codes
M CVV2/CVC2 match
N CVV2/CVC2 no match
P Not processed
S Merchant has indicated that CVV2/CVC2 is not present on card
U Issuer is not certified and/or has not provided Visa encryption keys

Appendix 3

Direct Post API

Result Code Table
100 Transaction was approved.
200 Transaction was declined by processor.
201 Do not honor.
202 Insufficient funds.
203 Over limit.
204 Transaction not allowed.
220 Incorrect payment information.
221 No such card issuer.
222 No card number on file with issuer.
223 Expired card.
224 Invalid expiration date.
225 Invalid card security code.
226 Invalid PIN.
240 Call issuer for further information.
250 Pick up card.
251 Lost card.
252 Stolen card.
253 Fraudulent card.
260 Declined with further instructions available. (See response text)
261 Declined-Stop all recurring payments.
262 Declined-Stop this recurring program.
263 Declined-Update cardholder data available.
264 Declined-Retry in a few days.
300 Transaction was rejected by gateway.
400 Transaction error returned by processor.
410 Invalid merchant configuration.
411 Merchant account is inactive.
420 Communication error.
421 Communication error with issuer.
430 Duplicate transaction at processor.
440 Processor format error.
441 Invalid transaction information.
460 Processor feature not available.
461 Unsupported card type.

Transaction Variables

Direct Post API

POST URL
POST URL: https://centavo.transactiongateway.com/api/transact.php
Sale/Authorization/Credit/Validate/Offline
Variable Name Description
type* The type of transaction to be processed.
Values: ‘sale’, ‘auth’, ‘credit’, ‘validate’, or ‘offline’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
payment_token The tokenized version of the customer’s card or check information. This will be generated by Collect.js and is usable only once.
googlepay_payment_data The encrypted token created when integration directly to the Google Pay SDK.
ccnumber** Credit card number.
ccexp** Credit card expiration date.
Format: MMYY
cvv The card security code. While this is not required, it is strongly recommended.
checkname*** The name on the customer’s ACH account.
checkaba*** The customer’s bank routing number.
checkaccount*** The customer’s bank account number.
account_holder_type The type of ACH account the customer has.
Values: ‘business’ or ‘personal’
account_type The ACH account entity of the customer.
Values: ‘checking’ or ‘savings’
sec_code The Standard Entry Class code of the ACH transaction.
Values: ‘PPD’, ‘WEB’, ‘TEL’, or ‘CCD’
amount Total amount to be charged. For validate, the amount must be omitted or set to 0.00.
Format: x.xx
surcharge Surcharge amount.
Format: x.xx
currency The transaction currency. Format: ISO 4217
payment*** The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’, ‘check’, or ‘cash’
processor_id If using Multiple MIDs, route to this processor (processor_id is obtained under Settings → Transaction Routing in the Control Panel).
authorization_code Specify authorization code. For use with “offline” action only.
dup_seconds Sets the time in seconds for duplicate transaction checking on supported processors. Set to 0 to disable duplicate checking. This value should not exceed 7862400.
descriptor Set payment descriptor on supported processors.
descriptor_phone Set payment descriptor phone on supported processors.
descriptor_address Set payment descriptor address on supported processors.
descriptor_city Set payment descriptor city on supported processors.
descriptor_state Set payment descriptor state on supported processors.
descriptor_postal Set payment descriptor postal code on supported processors.
descriptor_country Set payment descriptor country on supported processors.
descriptor_mcc Set payment descriptor mcc on supported processors.
descriptor_merchant_id Set payment descriptor merchant id on supported processors.
descriptor_url Set payment descriptor url on supported processors.
billing_method Should be set to ‘recurring’ to mark payment as a recurring transaction or ‘installment’ to mark payment as an installment transaction.
Values: ‘recurring’, ‘installment’
billing_number Specify installment billing number, on supported processors. For use when “billing_method” is set to installment.
Values: 0-99
billing_total Specify installment billing total on supported processors. For use when “billing_method” is set to installment.
order_template Order template ID.
order_description Order description.
Legacy variable includes: orderdescription
orderid Order Id
ipaddress IP address of cardholder, this field is recommended.
Format: xxx.xxx.xxx.xxx
tax**** Total tax amount.
shipping**** Total shipping amount
ponumber**** Original purchase order
first_name Cardholder’s first name.
Legacy variable includes: firstname
last_name Cardholder’s last name
Legacy variable includes: lastname
company Cardholder’s company
address1 Card billing address
address2 Card billing address, line 2
city Card billing city
state Card billing state.
Format: CC
zip Card billing zip code
country Card billing country.
Country codes are as shown in ISO 3166. Format: CC
phone Billing phone number
fax Billing fax number
email Billing email address
social_security_number Customer’s social security number, checked against bad check writers database if check verification is enabled.
drivers_license_number Driver’s license number.
drivers_license_dob Driver’s license date of birth.
drivers_license_state The state that issued the customer’s driver’s license.
shipping_firstname Shipping first name
shipping_lastname Shipping last name
shipping_company Shipping company
shipping_address1 Shipping address
shipping_address2 Shipping address, line 2
shipping_city Shipping city
shipping_state Shipping state
Format: CC
shipping_zip Shipping zip code
shipping_country Shipping country
Country codes are as shown in ISO 3166. Format: CC
shipping_email Shipping email address
merchant_defined_field_# You can pass custom information in up to 20 fields.
Format: merchant_defined_field_1=Value
customer_receipt If set to true, when the customer is charged, they will be sent a transaction receipt.
Values: ‘true’ or ‘false’
signature_image Cardholder signature image. For use with “sale” and “auth” actions only.
Format: base64 encoded raw PNG image. (16kiB maximum)
cardholder_auth‡‡ Set 3D Secure condition.
Values: ‘verified’ or ‘attempted’
eci‡‡ E-commerce indicator.
Values: ‘0’, ‘1’, ‘2’, ‘5’, ‘6’, or ‘7’
cavv‡‡ Cardholder authentication verification value.
Format: base64 encoded
xid‡‡ Cardholder authentication transaction id.
Format: base64 encoded
three_ds_version‡‡ 3DSecure version.
Examples: “1.0.2” or “2.0”
directory_server_id Directory Server Transaction ID. May be provided as part of 3DSecure 2.0 authentication.
Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
source_transaction_id Specifies a payment gateway transaction id in order to associate payment information with a Subscription or Customer Vault record. Must be set with a ‘recurring’ or ‘customer_vault’ action.
Recurring specific fields
recurring Recurring action to be processed.
Values: add_subscription
plan_id Create a subscription tied to a Plan ID if the sale/auth transaction is successful.
plan_payments The number of payments before the recurring plan is complete.
Note: Use ‘0’ for ‘until canceled’
plan_amount The plan amount to be charged each billing cycle.
Format: x.xx
day_frequency How often, in days, to charge the customer. Cannot be set with ‘month_frequency’ or ‘day_of_month’.
month_frequency How often, in months, to charge the customer. Cannot be set with ‘day_frequency’. Must be set with ‘day_of_month’.
Values: 1 through 24
day_of_month The day that the customer will be charged. Cannot be set with ‘day_frequency’. Must be set with ‘month_frequency’.
Values: 1 through 31 – for months without 29, 30, or 31 days, the charge will be on the last day
start_date The first day that the customer will be charged.
Format: YYYYMMDD
Customer Vault specific fields
customer_vault Associate payment information with a Customer Vault record if the transaction is successful.
Values: ‘add_customer’ or ‘update_customer’
customer_vault_id Specifies a customer vault id. If not set, the payment gateway will randomly generate a customer vault id.
Stored Credentials (CIT/MIT)
initiated_by Who initiated the transaction.
Values: ‘customer’ or ‘merchant’
initial_transaction_id Original payment gateway transaction id.
stored_credential_indicator The indicator of the stored credential.
Values: ‘stored’ or ‘used’
Use ‘stored’ when processing the initial transaction in which you are storing a customer’s payment details (customer credentials) in the Customer Vault or other third-party payment storage system.
Use ‘used’ when processing a subsequent or follow-up transaction using the customer payment details (customer credentials) you have already stored to the Customer Vault or third-party payment storage method.
Level III specific order fields
shipping Freight or shipping amount included in the transaction amount
Default: ‘0.00’
Format: x.xx
tax The sales tax, included in the transaction amount, associated with the purchase. Setting tax equal to ‘-1’ indicates an order that is exempt from sales tax.
Default: ‘0.00’
Format: x.xx
ponumber Purchase order number supplied by cardholder
orderid Identifier assigned by the merchant. This defaults to gateway transaction id.
shipping_country Shipping country (e.g. US)
Format: CC
shipping_postal Postal/ZIP code of the address where purchased goods will be delivered. This field can be identical to the ‘ship_from_postal’ if the customer is present and takes immediate possession of the goods.
ship_from_postal Postal/ZIP code of the address from where purchased goods are being shipped, defaults to merchant profile postal code.
summary_commodity_code 4 character international description code of the overall goods or services being supplied. The acquirer or processor will provide a list of current codes.
duty_amount Amount included in the transaction amount associated with the import of purchased goods.
Default: ‘0.00’
Format: x.xx
discount_amount Amount included in the transaction amount of any discount applied to complete order by the merchant.
Default: ‘0.00’
Format: x.xx
national_tax_amount The national tax amount included in the transaction amount.
Default: ‘0.00’
Format: x.xx
alternate_tax_amount Second tax amount included in the transaction amount in countries where more than one type of tax can be applied to the purchases.
Default: ‘0.00’
Format: x.xx
alternate_tax_id Tax identification number of the merchant that reported the alternate tax amount.
vat_tax_amount Contains the amount of any value added taxes which can be associated with the purchased item.
Default: ‘0.00’
Format: x.xx
vat_tax_rate Contains the tax rate used to calculate the sales tax amount appearing. Can contain up to 2 decimal places, e.g. 1% = 1.00.
Default: ‘0.00’
Format: x.xx
vat_invoice_reference_number Invoice number that is associated with the VAT invoice.
customer_vat_registration Value added tax registration number supplied by the cardholder.
merchant_vat_registration Government assigned tax identification number of the merchant for whom the goods or services were purchased from.
order_date Purchase order date, defaults to the date of the transaction.
Format: YYMMDD
Level III specific line item detail fields
item_product_code_# Merchant defined description code of the item being purchased.
item_description_# Description of the item(s) being supplied.
item_commodity_code_# International description code of the individual good or service being supplied. The acquirer or processor will provide a list of current codes.
item_unit_of_measure_# Code for units of measurement as used in international trade.
Default: ‘EACH’
item_unit_cost_# Unit cost of item purchased, may contain up to 4 decimal places.
item_quantity_# Quantity of the item(s) being purchased.
Default: ‘1’
item_total_amount_# Purchase amount associated with the item. Defaults to: ‘item_unit_cost_#’ x ‘item_quantity_#’ rounded to the nearest penny.
item_tax_amount_# Amount of tax on specific item, amount should not be included in ‘total_amount_#’.
Default: ‘0.00’
item_tax_rate_# Percentage representing the value-added tax applied.
Default: ‘0.00’
item_discount_amount_# Discount amount which can have been applied by the merchant on the sale of the specific item. Amount should not be included in ‘total_amount_#’.
item_discount_rate_# Discount rate for the line item. 1% = 1.00.
Default: ‘0.00’
item_tax_type_# Type of value-added taxes that are being used.
item_alternate_tax_id_# Tax identification number of the merchant that reported the alternate tax amount.
Always required
Required for credit card transactions
Required for ACH transactions
Required for Level 2 transactions
Required for Level 3 transactions
Required for offline transactions
Required for 3D Secure transactions

Notes:
  • Level II fields are required for Level II processing.
  • Level II and Level III fields are required for Level III processing.
  • You can pass only credit card or e-check transaction variables in a request, not both in the same request.
  • Certain banks may require some optional fields.


Capture
Variable Name Description
type* Type of transaction.
Values: ‘capture’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
transactionid* Original payment gateway transaction id
amount* Total amount to be settled. This amount must be equal to or less than the original authorized amount.
Format: x.xx
tracking_number Shipping tracking number
shipping_carrier Shipping carrier.
Values: ‘ups’, ‘fedex’, ‘dhl’, or ‘usps’
orderid Order id.
signature_image Cardholder signature image.
Format: base64 encoded raw PNG image. (16kiB maximum)
Always required

Void
Variable Name Description
type* Type of transaction.
Values: ‘void’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
transactionid* Original payment gateway transaction id
void_reason** Reason the EMV transaction is being voided.
Values: ‘fraud’, ‘user_cancel’, ‘icc_rejected’, ‘icc_card_removed’, ‘icc_no_confirmation’, or ‘pos_timeout’
payment*** The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’ or ‘check’
Always required
Conditionally required for EMV transactions
Required for ACH transactions

Refund
Variable Name Description
type* Type of transaction.
Values: ‘refund’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
transactionid* Original payment gateway transaction id
amount Total amount to be refunded. This amount may be equal to or less than the settled amount. Setting the amount to 0.00 will refund the entire amount.
Format: x.xx
payment** The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’ or ‘check’
Always required
Required for ACH transactions

Update
Variable Name Description
type* Type of transactions.
Values: ‘update’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
transactionid* Original payment gateway transaction id
payment** The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’ or ‘check’
tracking_number Shipping tracking number
shipping Total shipping amount.
Format: x.xx
shipping_postal Postal/ZIP code of the address where purchased goods will be delivered. This field can be identical to the ‘ship_from_postal’ if the customer is present and takes immediate possession of the goods.
ship_from_postal Postal/ZIP code of the address from where purchased goods are being shipped, defaults to merchant profile postal code.
shipping_country Shipping Country Code.
shipping_carrier Shipping carrier.
Values: ‘ups’, ‘fedex’, ‘dhl’, or ‘usps’
shipping_date Shipping date.
Format: YYYYMMDD
order_description Order Description.
Legacy variable includes: orderdescription
order_date Order date.
Format: YYYYMMDD
customer_receipt If set to true, when the customer is charged, they will be sent a transaction receipt.
Values: ‘true’ or ‘false’
signature_image Cardholder signature image.
Format: base64 encoded raw PNG image. (16kiB maximum)
ponumber Cardholder’s purchase order number.
summary_commodity_code 4 character international description code of the overall goods or services being supplied. The acquirer or processor will provide a list of current codes.
duty_amount Amount included in the transaction amount associated with the import of purchased goods.
Format: x.xx
discount_amount Amount included in the transaction amount of any discount applied to complete order by the merchant.
Format: x.xx
tax Tax amount.
Format: x.xx
national_tax_amount The national tax amount included in the transaction amount.
Format: x.xx
alternate_tax_amount Second tax amount included in the transaction amount in countries where more than one type of tax can be applied to the purchases.
Format: x.xx
alternate_tax_id Tax identification number of the merchant that reported the alternate tax amount.
vat_tax_amount Contains the amount of any value added taxes which can be associated with the purchased item.
vat_tax_rate Contains the tax rate used to calculate the sales tax amount appearing. Can contain up to 2 decimal places, e.g. 1% = 1.00.
vat_invoice_reference_number Invoice number that is associated with the VAT invoice.
customer_vat_registration Value added tax registration number supplied by the cardholder.
merchant_vat_registration Government assigned tax identification number of the merchant for whom the goods or services were purchased from.
merchant_defined_field_# Merchant Defined Fields.
Format: merchant_defined_field_1=Value
Always required
Required for ACH transactions

Recurring Variables

Direct Post API

POST URL
POST URL: https://centavo.transactiongateway.com/api/transact.php
Add a Plan
Variable Name Description
recurring* Add a recurring plan that subscriptions can be added to in the future.
Value: ‘add_plan’
plan_payments* The number of payments before the recurring plan is complete.
Notes: ‘0’ for until canceled
plan_amount* The plan amount to be charged each billing cycle.
Format: x.xx
plan_name* The display name of the plan.
plan_id* The unique plan ID that references only this recurring plan.
day_frequency** How often, in days, to charge the customer. Cannot be set with ‘month_frequency’ or ‘day_of_month’.
month_frequency*** How often, in months, to charge the customer. Cannot be set with ‘day_frequency’. Must be set with ‘day_of_month’.
Values: 1 through 24
day_of_month*** The day that the customer will be charged. Cannot be set with ‘day_frequency’. Must be set with ‘month_frequency’.
Values: 1 through 31 – for months without 29, 30, or 31 days, the charge will be on the last day
Always required
Required unless ‘month_frequency’ and ‘day_of_month’ is set.
Required unless ‘day_frequency’ is set.

Add a Subscription to an Existing Plan
Variable Name Description
recurring* Associate payment information with a recurring plan.
Value: add_subscription
plan_id* The plan ID of the plan that the subscription will be associated with.
start_date The first day that the customer will be charged.
Format: YYYYMMDD
payment_token The tokenized version of the customer’s card or check information. This will be generated by Collect.js and is usable only once.
googlepay_payment_data The encrypted token created when integration directly to the Google Pay SDK.
ccnumber** Credit card number.
ccexp** Credit card expiration.
Format: MMYY
payment*** The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’ or ‘check’
checkname*** The name on the customer’s ACH account.
checkaccount*** The customer’s bank account number.
checkaba*** The customer’s bank routing number.
account_type The customer’s ACH account type.
Values: ‘checking’ or ‘savings’
currency Set transaction currency.
account_holder_type The customer’s ACH account entity.
Values: ‘personal’ or ‘business’
sec_code ACH standard entry class codes.
Values: ‘PPD’, ‘WEB’, ‘TEL’, or ‘CCD’
first_name Cardholder’s first name.
Legacy variable includes: firstname
last_name Cardholder’s last name.
Legacy variable includes: lastname
address1 Card billing address.
city Card billing city
state Card billing state.
zip Card billing postal code.
country Card billing country code.
phone Billing phone number.
email Billing email address.
company Cardholder’s company.
address2 Card billing address, line 2.
fax Billing fax number.
orderid Order ID
order_description Order Description
merchant_defined_field_# Can be set up in merchant control panel under ‘Settings’->’Merchant Defined Fields’.
ponumber Cardholder’s purchase order number.
processor_id If using Multiple MIDs, route to this processor (processor_id is obtained under Settings->Transaction Routing in the Control Panel).
customer_receipt If set to true, when the customer is charged, they will be sent a transaction receipt.
Values: ‘true’ or ‘false’
source_transaction_id Specifies a payment gateway transaction id in order to associate payment information with a Subscription record.
Always required
Required for credit card transactions
Required for ACH transactions

Adding a Custom Subscription
Variable Name Description
recurring* Add a custom recurring subscription that is NOT associated with an existing plan
Value: ‘add_subscription’
plan_payments* The number of payments before the recurring plan is complete.
Notes: ‘0’ for until canceled
plan_amount* The plan amount to be charged each billing cycle.
Format: x.xx
day_frequency** How often, in days, to charge the customer. Cannot be set with ‘month_frequency’ or ‘day_of_month’.
month_frequency*** How often, in months, to charge the customer. Cannot be set with ‘day_frequency’. Must be set with ‘day_of_month’.
Values: 1 through 24
day_of_month*** The day that the customer will be charged. Cannot be set with ‘day_frequency’. Must be set with ‘month_frequency’.
Values: 1 through 31 – for months without 29, 30, or 31 days, the charge will be on the last day
start_date The first day that the customer will be charged.
Format: YYYYMMDD
payment_token The tokenized version of the customer’s card or check information. This will be generated by Collect.js and is usable only once.
googlepay_payment_data The encrypted token created when integration directly to the Google Pay SDK.
ccnumber**** Credit card number.
ccexp**** Credit card expiration.
Format: MMYY
payment The type of payment.
Default: ‘creditcard’
Values: ‘creditcard’ or ‘check’
checkname The name on the customer’s ACH account.
checkaccount The customer’s bank account number.
checkaba The customer’s bank routing number.
account_type The customer’s ACH account type.
Values: ‘checking’ or ‘savings’
account_holder_type The customer’s ACH account entity.
Values: ‘personal’ or ‘business’
sec_code ACH standard entry class codes.
Values: ‘PPD’, ‘WEB’, ‘TEL’, or ‘CCD’
first_name Cardholder’s first name.
Legacy variable includes: firstname
last_name Cardholder’s last name.
Legacy variable includes: lastname
address1 Card billing address.
city Card billing city
state Card billing state.
zip Card billing postal code.
country Card billing country code.
phone Billing phone number.
email Billing email address.
company Cardholder’s company.
address2 Card billing address, line 2.
fax Billing fax number.
orderid Order ID
order_description Order Description
Legacy variable includes: orderdescription
merchant_defined_field_# Can be set up in merchant control panel under ‘Settings’->’Merchant Defined Fields’.
ponumber Cardholder’s purchase order number.
processor_id If using Multiple MIDs, route to this processor (processor_id is obtained under Settings->Transaction Routing in the Control Panel).
customer_receipt If set to true, when the customer is charged, they will be sent a transaction receipt.
Values: ‘true’ or ‘false’
source_transaction_id Specifies a payment gateway transaction id in order to associate payment information with a Subscription record.
Always required
Required unless ‘month_frequency’ and ‘day_of_month’ is set
Required unless ‘day_frequency’ is set
Required for credit card transactions
Required for ACH transactions

Update a Subscription’s Billing Information
Variable Name Description
recurring* Update the subscription’s billing information.
Value: ‘update_subscription’
subscription_id* The subscription ID that will be updated.
Always required

Delete a Subscription
Variable Name Description
recurring* Delete the subscription. Customer will no longer be charged.
Value: ‘delete_subscription’
subscription_id* The subscription ID that will be deleted.
Always required

Transaction Response Variables

Direct Post API

Standard Response
Variable Name Description
response 1 = Transaction Approved
2 = Transaction Declined
3 = Error in transaction data or system error
responsetext Textual response
authcode Transaction authorization code.
transactionid Payment gateway transaction id.
avsresponse AVS response code (See Appendix 1).
cvvresponse CVV response code (See Appendix 2).
orderid The original order id passed in the transaction request.
response_code Numeric mapping of processor responses (See Appendix 3).
emv_auth_response_data This will optionally come back when any chip card data is provided on the authorization. This data needs to be sent back to the SDK after an authorization.

Invoicing Variables

Direct Post API

POST URL
POST URL: https://centavo.transactiongateway.com/api/transact.php
Create Invoice
Variable Name Description
invoicing* Create a new invoice and email it to the customer.
Values: ‘add_invoice’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
amount* Total amount to be invoiced. Must be greater than 0.00.
Format: x.xx
email* Billing email address
An invoice will be sent to this address when it is created.
payment_terms When the invoice should be paid
Default: ‘upon_receipt’
Values: ‘upon_receipt’, or integers from 0-999.
payment_methods_allowed What payment methods a customer may use when paying invoice.
Defaults to all available payment methods available in your merchant account
Values: ‘cc’, ‘ck’, and ‘cs’. Multiple payment types can be selected by comma-separating values.
currency The transaction currency.
Format: ISO 4217
order_description Order description.
Legacy variable includes: orderdescription
orderid Order ID.
customer_id Customer ID.
customer_tax_id Customer Tax ID.
tax Total tax amount.
shipping Total shipping amount.
ponumber Original purchase order.
first_name Cardholder’s first name.
Legacy variable includes: firstname
last_name Cardholder’s last name.
Legacy variable includes: lastname
company Cardholder’s company.
address1 Card billing address.
address2 Card billing address, line 2.
city Card billing city.
state Card billing state.
Format: CC
zip Card billing zip code.
country Card billing country.
Country codes are as shown in ISO 3166. Format: CC
phone Billing phone number.
fax Billing fax number.
website Customer website.
shipping_firstname Shipping first name.
shipping_lastname Shipping last name.
shipping_company Shipping company.
shipping_address1 Shipping address.
shipping_address2 Shipping address, line 2.
shipping_city Shipping city.
shipping_state Shipping state.
Format: CC
shipping_zip Shipping zip code.
shipping_country Shipping country.
Country codes are as shown in ISO 3166. Format: CC
shipping_email Shipping email address.
merchant_defined_field_# You can pass custom information in up to 20 fields.
Format: merchant_defined_field_1=Value
Product Information
item_product_code_# Merchant defined description code of the item being purchased.
item_description_# Description of the item(s) being supplied.
item_commodity_code_# International description code of the individual good or service being supplied. The acquirer or processor will provide a list of current codes.
item_unit_of_measure_# Code for units of measurement as used in international trade.
Default: ‘EACH’
item_unit_cost_# Unit cost of item purchased, may contain up to 4 decimal places.
item_quantity_# Quantity of the item(s) being purchased.
Default: ‘1’
item_total_amount_# Purchase amount associated with the item. Defaults to: ‘item_unit_cost_#’ x ‘item_quantity_#’ rounded to the nearest penny.
item_tax_amount_# Amount of tax on specific item, amount should not be included in ‘total_amount_#’.
Default: ‘0.00’
item_tax_rate_# Percentage representing the value-added tax applied.
Default: ‘0.00’
item_discount_amount_# Discount amount which can have been applied by the merchant on the sale of the specific item. Amount should not be included in ‘total_amount_#’.
item_discount_rate_# Discount rate for the line item. 1% = 1.00.
Default: ‘0.00’
item_tax_type_# Type of value-added taxes that are being used.
item_alternate_tax_id_# Tax identification number of the merchant that reported the alternate tax amount.
Always required

Update Invoice
Variable Name Description
invoicing* Update an existing invoice.
Values: ‘update_invoice’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
invoice_id* The invoice ID to be updated.
Always required
Notes:

All variables (besides currency) on an invoice may be updated. Updating an invoice will not result in a new invoice being sent to the customer. To send the invoice after updating an invoice, use the send_invoice request after making changes.


Send Invoice
Variable Name Description
invoicing* Send an existing invoice to a customer.
Values: ‘send_invoice’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
invoice_id* The invoice ID to be emailed.
Always required
Notes:

The invoice will be sent to the billing email address assigned to the invoice.


Close Invoice
Variable Name Description
invoicing* The invoice to be closed.
Values: ‘close_invoice’
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
invoice_id* The invoice ID to be closed.
Always required

Product Manager Variables

Direct Post API

POST URL
POST URL: https://centavo.transactiongateway.com/api/transact.php
Add a Product
Variables Description
products* Add a product to the Product Manager.
Value: “add_product“
product_sku* The unique SKU for this product. An error will be returned if the SKU is already in use by another product.
Examples: “000001” or “324-6323-0005“
product_description* The user-facing name of the product.
Examples: “1 Gallon Milk” or “Phone Case”
product_cost* The cost of the product before any tax or discounts. Must be greater than 0.00.
product_currency* The currency for the product’s price.
Examples: “USD” or “EUR”
product_commodity_code The commodity code for the product.
product_unit_of_measure The unit of measure for the product. Defaults to “NAR” (number of articles).
Examples: “TDK” or “MTQ”
product_tax_amount The tax that should be added to the product cost. This is a fixed amount, not a percentage.
Example: “1.54”
product_discount_amount The discount that will subtracted from the cost of the product.
product_image_data** The Base64-encoded version of the image for the product. The format must be JPG, PNG, or GIF, and be 2MB or smaller.
product_image_name** The file name of the image being added with product_image_data.
Examples: “product.png” or “sku-1234.jpg”
Always required
Required if adding an image to the product

Update a Product
Variables Description
products* Update a product already in the Product Manager.
Value: “update_product”
product_id* The automatically generated ID for the product. This was returned in the add_product API response, or can be found in the UI under the Product Details page in the Product Manager.
Example: “5538585252”
product_sku The unique SKU for this product. An error will be returned if the SKU is already in use by another product.
Examples: “000001” or “324-6323-0005”
product_description The user-facing name of the product.
Examples: “1 Gallon Milk” or “Phone Case”
product_cost The cost of the product before any tax or discounts. Must be greater than 0.00.
product_currency The currency for the product’s price.
Examples: “USD” or “EUR”
product_commodity_code The commodity code for the product.
product_unit_of_measure The unit of measure for the product.
Examples: “TDK” or “MTQ”
product_tax_amount The tax that should be added to the product cost. This is a fixed amount, not a percentage.
Example: “1.54”
product_discount_amount The discount that will subtracted from the cost of the product.
product_image_data** The Base64-encoded version of the image for the product. The format must be JPG, PNG, or GIF, and be 2MB or smaller.
product_image_name** The file name of the image being added with product_image_data.
Examples: “product.png” or “sku-1234.jpg”
Always required
Required if adding an image to the product

Delete a Product
Variables Description
products* Delete a product to the Product Manager. This action can not be undone.
Value: “delete_product”
product_id* The automatically generated ID for the product. This was returned in the add_product API response, or can be found in the UI under the Product Details page in the Product Manager.
Example: “5538585252”
Always required

Retail Data

Direct Post API

Passing Unencrypted Retail Magnetic Stripe Data
Variable Name Description
track_1 Raw Magnetic Stripe Data
track_2 Raw Magnetic Stripe Data
track_3 Raw Magnetic Stripe Data

Passing MagTek Magensa Encrypted Magnetic Stripe Data
Variable Name Description
magnesafe_track_1 Raw MagTek Magensa Data
magnesafe_track_2 Raw MagTek Magensa Data
magnesafe_magneprint Raw MagTek Magensa Data
magnesafe_ksn Raw MagTek Magensa Data
magnesafe_magneprint_status Raw MagTek Magensa Data

Passing IDTech M130 Encrypted Swipe Data
Variable Name Description
encrypted_track_1 Raw encrypted data
encrypted_track_2 Raw encrypted data
encrypted_track_3 Raw encrypted data
encrypted_ksn Raw encrypted data

Passing IDTech M130 Encrypted Keyed Data
Variable Name Description
encrypted_data Raw encrypted data

Passing Ingenico Telium 2 Chip Card Data
Variable Name Description
entry_mode The type of transaction data to be processed.
Value: ’emv_icc’
emv_auth_request_data EMV Data for the transaction as received from the EMV Chip Card SDK.
emv_device The EMV – capable card reader.
Value: ‘ingenico_rba’
verification_method Method used to verify the EMV transaction.
Values: ‘signature’, ‘offline_pin’, ‘offline_pin_signature’, or ‘none’
encrypted_ksn Raw encrypted data
encrypted_track_2 Raw encrypted data

Passing Ingenico Telium 2 Swipe Data
Variable Name Description
entry_mode The type of transaction data to be processed.
Values: ‘swiped’ or ‘swiped_emv_fallback’
emv_device The EMV – capable card reader.
Value: ‘ingenico_rba’
encrypted_ksn Raw encrypted data
encrypted_track_1 Raw encrypted data
encrypted_track_2 Raw encrypted data

Passing Ingenico Telium 2 NFC Data
Variable Name Description
entry_mode The type of transaction data to be processed.
Value: ‘nfc_msd’
emv_device The EMV – capable card reader.
Value: ‘ingenico_rba’
encrypted_ksn Raw encrypted data
encrypted_track_2 Raw encrypted data

Passing Ingenico Telium 2 Keyed Data
Variable Name Description
entry_mode The type of transaction data to be processed.
Value: ‘keyed’
emv_device The EMV – capable card reader.
Value: ‘ingenico_rba’
encrypted_ksn Raw encrypted data
encrypted_track_2 Raw encrypted data

Testing Information

Direct Post API

Transaction Testing Methods
Method 1: Put your account in test mode

Transactions can be submitted to any merchant account that is in test mode. Keep in mind that if an account is in test mode, all valid credit cards will be approved but no charges will actually be processed and nothing will be sent to the credit card or ACH processor.


Method 2: Send in a one-off test transaction

One-off test transactions can be processed using the below test_mode variable. This will process this singular transaction in test mode, but it will not impact anything else on the account. An example use case would be running test transactions in a developent environment while your website is actively processing real transactions from customers.

test_mode:
If set to “enabled” and providing one of the test credit card numbers listed below with “1025” as the expiration date, the single transaction will process in test mode. To see this transaction in reporting, you will need to toggle your account to test mode, but the Direct Post API testing can be done without doing this.


Method 3: Dedicated test account

The Payment Gateway Demo Account can be used for testing at any time. Please use the below security key for testing with this account. This account is always available and allows testing in a completely sandboxed environment. Like all testing methods, no card or check data will ever be sent for actual processing.

security_key: 6457Thfj624V5r7WUwc5v6a68Zsd6YEm


Transaction POST URL

Transaction details should be POST’ed to the following URL:

POST URL: https://centavo.transactiongateway.com/api/transact.php
Test Data

Transactions can be submitted using the following information:

Visa: 4111111111111111
MasterCard: 5431111111111111
Discover: 6011601160116611
American Express: 341111111111111
Diner’s Club: 30205252489926
JCB: 3541963594572595
Maestro: 6799990100000000019
Credit Card Expiration: 10/25
account (ACH): 123123123
routing (ACH): 123123123


Triggering Errors in Test Mode
  • To cause a declined message, pass an amount less than 1.00.
  • To trigger a fatal error message, pass an invalid card number.
  • To simulate an AVS match, pass 888 in the address1 field, 77777 for zip.
  • To simulate a CVV match, pass 999 in the cvv field.


Partial Payment Information

Direct Post API

Request Details
Variable Description
partial_payment_id Unique identifier returned when making the original transaction. This should only be used for secondary transactions.
partial_payments This variable allows the following two values to be passed to it:
settle_partial: Settles any amount of tender collected (captured partial auth’s and approved partial sales) at cut off.
payment_in_full: Required that any split tendered transaction is collected in-full before settlement gets initiated.
type This variable can be passed the value ‘complete_partial_payment’ which will complete a payment_in_full transaction that has not been collected in full. This allows industries that require payment_in_full but subsequently decide to still settle the transaction even though it has not been collected in full.

Response Details
Variable Description
partial_payment_id A numeric identifier which is used when submitting subsequent transactions.
partial_payment_balance Returns the payment’s remaining balance.
amount_authorized Provides the amount that was authorized.

Examples

Example 1:
In this request, if nothing more was done, a transaction for 30.00 would settle at the next cut-off.

Request …type=sale&partial_payments=settle_partial&ccnumber=4111111111111111&ccexp=1016&amount=100.00…
Response …response=1&partial_payment_id=123456789&partial_payment_balance=70.00
&amount_authorized=30.00…

Example 2:
In this request, payment_in_full was required and two transaction were collected – this transaction would settle at the next cut-off.

Request 1 …type=sale&partial_payments=payment_in_full&ccnumber=4111111111111111
&ccexp=1016&amount=100.00…
Response 1 …response=1&partial_payment_id=123456789&partial_payment_balance=70.00&
amount_authorized=30.00…
Request 2 …type=sale&partial_payment_id=123456789&partial_payments=payment_in_full
&ccnumber=4000000000000002&ccexp=1016&amount=70.00…
Response 2 …response=1& partial_payment_id=123456789&partial_payment _balance=0.00&
amount_authorized=70.00…

Example 3:
In this example, payment_in_full was required and two transactions were attempted, but only one collected. The merchant decided to force it out anyways – this transaction would settle at the next cut-off.

Request 1 …type=sale&partial_payments=payment_in_full&ccnumber=4111111111111111
&ccexp=1016&amount=100.00…
Response 1 …response=1&partial_payment_id=123456789&partial_payment_balance=70.00
&amount_authorized=30.00…
Request 2 …type=sale&partial_payment_id=123456789&partial_payments=payment_in_full
&ccnumber=4000000000000002&ccexp=1016&amount=70.00…
Response 2 …response=2&partial_payment_id=123456789&partial_payment_balance=70.00
&amount_authorized=70.00…
Request 3 …type=complete_partial_payment& partial_payment_id=123456789
&partial_payments=payment_in_full&amount=70.00…
Response 3 …response=1& partial_payment_id=123456789&partial_payment_balance=0.00
&amount_authorized=70.00…


Credential on File Information

Direct Post API

Please note the below is meant to be a guide for how the platform supports CIT and MIT use cases. This is not meant to be an exhaustive list of items needed in order to be compliant. For more information on CIT/MIT compliance, please consult your processor.

Credential on File regulations apply any time data is stored to process future purchases for a cardholder.

Customer vs Merchant Initiated

When a customer is actively engaged in checkout – either physical present in a store, or checking out online in their browser, that is a Customer Initiated Transaction (CIT).

When the customer isn’t actively engaged, but has given permission for their card to be charged, that is a Merchant Initiated Transaction (MIT). In order for a merchant to submit a Merchant Initiated Transaction, a Customer Initiated transaction is required first.


Overview

A cardholder’s consent is required for the initial storage of credentials. When a card is stored, an initial transaction should be submitted (Validate, Sale, or Auth) with the correct credential-on-file type. The transaction must be approved (not declined or encounter an error.) Then, store the transaction ID of the initial customer initiated transaction. The transaction ID must then be submitted with any follow up transactions (MIT or CIT.)

Credential on File types include Recurring, Installment, and Unscheduled types.

For simplicity – we are using the Direct Post API variables. These match the names of the Batch Upload, Collect.js, or the Browser Redirect APIs. The Three-Step API follows the same pattern, and the variables should be submitted on Step 1.


Request Details
Variable Description
initiated_by Who initiated the transaction.
Values: ‘customer’ or ‘merchant’
initial_transaction_id Original payment gateway transaction id.
stored_credential_indicator The indicator of the stored credential.
Values: ‘stored’ or ‘used’
Use ‘stored’ when processing the initial transaction in which you are storing a customer’s payment details (customer credentials) in the Customer Vault or other third-party payment storage system.
Use ‘used’ when processing a subsequent or follow-up transaction using the customer payment details (customer credentials) you have already stored to the Customer Vault or third-party payment storage method.

Response Details
Variable Description
cof_supported Credential on File support indicator specific to the transaction.
Values: ‘stored’ or ‘used’
Value will be ‘stored’ if CIT/MIT transaction was sent to a processor that supports the feature.
Value will be ‘used’ if CIT/MIT transaction was sent to a processor that does not support the feature or if a merchant-initiated transaction cannot occur due to Cross-Processor limitations.

Please Note: For Three-Step Redirect transactions, the request details must be sent in Step 1 and the ‘cof-supported’ element will be returned in the response of Step 3.

Recurring:

A transaction in a series of transactions that uses a stored credential and are processed at fixed, regular intervals (not to exceed one year between transactions), and represents cardholder agreement for the merchant to initiate future transactions for the purchase of goods or services provided at regular intervals.

If a customer is signing up for a recurring subscription, the merchant is expected to send “an initial recurring transaction” every time the customer signs up for a new recurring subscription.

For an initial transaction:
  • For a free trial, the initial transaction will be a validate transaction type (or auth if validate is not supported.)
  • If the customer is being charged immediately for a product, the initial transaction will be a sale or an authorization for the correct amount.
Either transaction MUST INCLUDE three items:
  • billing_method=recurring
  • initiated_by=customer
  • stored_credential_indicator=stored

Examples

Example 1: In this request, an initial recurring sale is sent and an approved transaction is returned in the response. Store this transaction for the follow up request.

Request …type=sale&billing_method=recurring&initiated_by=customer
&stored_credential_indicator=stored…
Response …response=1&responsetext=Approved&transactionid=1234567890…

The transaction ID would be stored and submitted on follow up transactions. The follow up transaction(s) would include:

  • billing_method=recurring
  • initiated_by=merchant
  • stored_credential_indicator=used
  • initial_transaction_id=XXXXXXXXXX

Example 2: In this request, the subsequent merchant initiated sale is processed using the stored transaction from Example 1.

Request …type=sale&billing_method=recurring&initiated_by=merchant
&stored_credential_indicator=used&initial_transaction_id=1234567890…
Response …response=1&responsetext=Approved&transactionid=1234567891…

Please Note: This transaction ID cannot be used for “unscheduled” or “installment” credential-on-file transactions.

Installment:

An “installment” transaction is a series of transactions that uses a stored credential and represents cardholder agreement with the merchant to initiate one or more future transactions over a period of time for a single purchase of goods or services.

Installment transactions work just like Recurring in that you need a customer initiated transaction for a subsequent installment transaction. The difference is the billing_method will be “installment”.

The customer initiated transaction MUST INCLUDE at least three items (* recommended to send, if available):

  • billing_method=installment
  • initiated_by=customer
  • stored_credential_indicator=stored
  • * billing_total
  • * billing_number (Values: 0-99)

Examples

Example 3: In this request, an initial installment sale is sent and an approved transaction is returned in the response. Store this transaction for the follow up request.

Request …type=sale&billing_method=installment&initiated_by=customer&stored_credential_indicator=stored
&billing_total=100.00&billing_number=1&amount=25.00…
Response …response=1&responsetext=Approved&transactionid=1234567890…

The transaction ID would be stored and submitted on follow up transactions. The follow up transaction(s) would include (* recommended to send, if available):

  • billing_method=installment
  • initiated_by=merchant
  • stored_credential_indicator=used
  • initial_transaction_id=XXXXXXXXXX
  • * billing_total
  • * billing_number

Example 4: In this request, the subsequent merchant initiated sale is processed using the stored transaction from Example 3.

Request …type=sale&billing_method=installment&initiated_by=merchant&stored_credential_indicator=used
&initial_transaction_id=1234567890&billing_total=100.00&billing_number=1&amount=25.00…
Response …response=1&responsetext=Approved&transactionid=1234567891…

Please Note:

This transaction ID cannot be used for “unscheduled” or “recurring” card on file transactions.


Unscheduled Credential On File:

For payments that aren’t recurring or installment – there are unscheduled options as well.

The first customer initiated transaction will include these two items (no billing method):

  • initiated_by=customer
  • stored_credential_indicator=stored

Examples

Example 5: In this request, an initial unscheduled sale is sent and an approved transaction is returned in the response. Store this transaction for the follow up request.

Request …type=sale&initiated_by=customer
&stored_credential_indicator=stored…
Response …response=1&responsetext=Approved&transactionid=1234567890…

The transaction ID can be used, without a billing method, for a customer initiated or merchant initiated transaction.

Please Note: The transaction ID cannot be used for a “recurring” or “installment” transaction.

Unscheduled, Customer Initiated:

A card-absent transaction initiated by the cardholder where the cardholder does not need to enter their card details as the merchant uses the payment credential previously stored by the cardholder to perform the transaction. Examples include a transaction using customer’s merchant profile or digital wallet.

This is your typical shopping cart scenario where the customer checks out without having to re-enter their card details.

The follow up transaction(s) would include:

  • initiated_by=customer
  • stored_credential_indicator=used

Example 6: In this request, a subsequent unscheduled sale is sent and an approved transaction is returned in the response.

Request …type=sale&initiated_by=customer&stored_credential_indicator=used…
Response …response=1&responsetext=Approved&transactionid=1234567891…

Unscheduled, Merchant Initiated: A transaction using a stored credential for a fixed or variable amount that does not occur on a scheduled or regularly occurring transaction date, where the cardholder has provided consent for the merchant to initiate one or more future transactions. An example of this transaction is an account auto-top up transaction.

An example of an account auto-top up would be a customer with an account with a balance. When that balance gets low, the customer’s card is charged automatically, without the customer’s involvement.

The follow up transaction(s) would include:

  • initiated_by=merchant
  • stored_credential_indicator=used
  • initial_transaction_id=XXXXXXXXXX

Example 7: In this request, a subsequent unscheduled sale is sent and an approved transaction is returned in the response.

Request …type=sale&initiated_by=merchant&stored_credential_indicator=used
&initial_transaction_id=1234567890…
Response …response=1&responsetext=Approved&transactionid=1234567892…

Appendix 1: Recommend Further Reading:

If there is any question where a transaction type falls, we recommend reviewing the official card brand documentation. Visa’s guidelines are the most stringent, and generally if you follow those guidelines, you’ll also be compliant for MasterCard, American Express and Discover.

Visa:
https://usa.visa.com/dam/VCOM/global/support-legal/documents/stored-credential-transaction-framework-vbs-10-may-17.pdf
MasterCard:
https://www.mastercard.us/en-us/consumers/offers-promotions/credential-on-file-payments.html



Google Pay

Google Pay allows your customers to submit payment data via a payment method they trust. This also enables you to collect their payment information in a tokenized form so that the plain text credit card information never touches your environment.

Set Up

Google Pay documentation can be found here. Those documents are maintained by Google and will be kept up to date with any changes and enhancements to the Google Pay SDK.

When setting up your merchant account in the Google Pay Business Console, Google will ask if you are doing a “Direct” or “Gateway” integration; you should select “Gateway.” The SDK will ask you to provide “gateway” and “gatewayMerchantId” values.

gateway “gatewayservices”
gatewayMerchantId Your “Gateway ID” as listed in the Account Information settings page of the merchant control panel.

Overview

While Google’s documentation will have specific details for using the Google Pay SDK, this is an overview of what the integration process and user flow should look like.

  1. Customer arrives at your checkout page. This page has the Google Pay SDK implemented and draws the Google Pay button.
  2. If the customer clicks on the Google Pay button, the Google Pay SDK will open a window for the customer to select their payment information.
  3. The user confirms their payment information, which closes the new window and returns the user to your site.
  4. Your software will receive a tokenized version of the customer’s payment information from the Google Pay SDK.
  5. That tokenzied payload should be passed to the gateway for decryption as a part of your Direct Post API request. The card, contact, and shipping information in this token will be stored to the transaction data when it’s processed by the gateway.
Variable Name Description
googlepay_payment_data The encrypted token created by the Google Pay SDK.

In the event that there is data in the Direct Post request and the Google Pay token, such as the customer’s zip code, the gateway will prefer the value in the Google Pay token, as that is what the customer explicitly provided.

Example

Below is a code example of how to use Google Pay on a basic website.


<div id="container"></div>

    <script>
        let paymentsClient = null;
    
        function getGooglePaymentsClient() {
            if ( paymentsClient === null ) {
                paymentsClient = new google.payments.api.PaymentsClient({environment: 'TEST'});
            }
            return paymentsClient;
        }
    
        function onGooglePayLoaded() {
            const paymentsClient = getGooglePaymentsClient();
            paymentsClient.isReadyToPay({
                apiVersion: 2,
                apiVersionMinor: 0,
                allowedPaymentMethods: [
                    {
                        type: 'CARD',
                        parameters: {
                            allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
                            allowedCardNetworks: ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"]
                        }
                    }
                ]
            })
                .then(function(response) {
                    if (response.result) {
                        addGooglePayButton();
                    }
                })
                .catch(function(err) {
                    // show error in developer console for debugging
                    console.error(err);
                });
        }
    
        function addGooglePayButton() {
            const paymentsClient = getGooglePaymentsClient();
            const button =
                paymentsClient.createButton({onClick: onGooglePaymentButtonClicked});
            document.getElementById('container').appendChild(button);
        }
    
        function onGooglePaymentButtonClicked() {
            const paymentDataRequest = {
                apiVersion: 2,
                apiVersionMinor: 0,
                allowedPaymentMethods: [{
                    type: 'CARD',
                    parameters: {
                        allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
                        allowedCardNetworks: ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"]
                    },
                    tokenizationSpecification: {
                        type: 'PAYMENT_GATEWAY',
                        parameters: {
                            'gateway': 'gatewayservices',
                            'gatewayMerchantId': '[MerchantID]' // This value is located in the account information settings page
                        }
                    }
                }],
                transactionInfo: {
                    countryCode: 'US',
                    currencyCode: 'USD',
                    totalPriceStatus: 'FINAL',
                    totalPrice: '1.00'
                },
                merchantInfo: {
                    merchantId: '01234567890123456789',
                },
                emailRequired: true
            }
    
            const paymentsClient = getGooglePaymentsClient();
            paymentsClient.loadPaymentData(paymentDataRequest)
                .then(function(paymentData) {
                    // handle the response
                    processPayment(paymentData);
                })
                .catch(function(err) {
                    // show error in developer console for debugging
                    console.error(err);
                });
        }
    
        function processPayment(paymentData) {
            console.log(paymentData);
        }
    </script>
    
    <script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"></script>
    




Apple pay

Direct Post API

Supported Processors

Currently Apple Pay is supported only on the TSYS – EMV platform.

Configuring Apple Pay

Creating an Apple Merchant ID
First, you must obtain an Apple Merchant ID before you can generate the Certificate Signing Request that Apple requires. You will need to set up an Apple Merchant ID in your iOS Developer Account. Follow these steps to complete the setup:

  1. Go to Apple’s Developer Portal and log in to the Member Center to create a new Merchant ID.
  2. Navigate to the Certificates, Identifiers, and Profiles area of the Member Center, and then begin the Register Merchant ID process.
  3. You must then set the Apple Merchant ID within your gateway Control Panel under Settings -> Apple Pay.

Generating the Certificate Signing Request
Next, you will need to associate a Certificate with the Merchant ID in Apple’s Developer Portal. After downloading the Certificate Signing Request from the gateway’s options page, follow these steps.

  1. In Apple’s Developer Portal, click on the Merchant ID and then click “Edit”.
  2. Click “Create Certificate”.
  3. You are obtaining a CSR file from a Payment Provider so you will not have to create one. Click “Continue” to proceed to the upload page.
  4. Click “Choose File…” and select the Gateway.certSigningRequest file you downloaded from the gateway’s options page.

How to Obtain Apple Pay Payment Data

PassKit provides the payment data in the (PKPayment *)payment that is returned to your app’s paymentAuthorizationViewController:didAuthorizePayment:completion method. The Apple Pay encrypted payment data is found in payment.token.paymentData.

Payment.token.paymentData is a binary (NSData) object, so you must encode it as a hexadecimal string before it can be passed to the Gateway.


Passing Apple Pay Payment Data

To submit a payment with Apple Pay, send the encrypted token data into the applepay_payment_data variable. There is no need to decrypt the data in your app. Only the Gateway will have access to the private key that can decrypt the token.


Notes

When passing in applepay_payment_data, you should not include the variables ccnumber or ccexp; they are extracted from the token data.

Important Note: The authorization amount must match the amount the customer approves in the app. If you pass in a currency, that must also match the currency approved in the app. If omitted, the currency from the app is used.

For working example code, including how to obtain the PKPayment object and how to pass a simple transaction to the Gateway, download the sample project.


Variables
Variable Name Description
applepay_payment_data The encrypted Apple Pay payment data (payment.token.paymentData) from PassKit encoded as a hexadecimal string

Troubleshooting

If you receive the error “Failed to decrypt Apple Pay data. Ensure that the Apple Pay Merchant ID is correct in the Gateway Settings and that the certificate was generated from a Gateway Certificate Signing Request.”, try these steps:

  1. Verify that the Merchant ID that Apple has in the developer portal exactly matches the Merchant ID in the Gateway’s settings.
  2. Verify that your app’s PKPaymentRequest’s merchantIdentifier exactly matches the Merchant ID in the Gateway’s settings.
  3. Ensure that the correct Merchant ID is checked in the Apple Pay section of the Capabilities tab in your project’s target settings.
  4. Try creating a new Merchant ID. Reusing an existing Merchant ID with a new certificate may sometimes cause issues with encryption.



    ' ***** DISCLAIMER *****
    ' This code is to be used as an example and not in production.
    ' It lacks thorough testing and debugging.  The Results below will be
        ' returned when posting against a gateway Test Account or an Active Account with Test Mode Enabled
    
    
    
    GatewaySecurityKey = "[[Gateway Security Key Here]]"
    
    ' Returns True on Success, False on Failure
    Function GatewaySale(amount, ccnumber, ccexp, cvv, name, address, zip)
        Set OGateway = Server.CreateObject("MSXML2.ServerXMLHTTP")
        OGateway.Open "POST", "https://centavo.transactiongateway.com/api/transact.php", false
        OGateway.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
        DataToSend = "security_key=" & Server.URLEncode(GatewaySecurityKey) &_
                 "&ccnumber=" & Server.URLEncode(ccnumber) &_
                 "&ccexp=" & Server.URLEncode(ccexp) &_
                 "&cvv=" & Server.URLEncode(cvv) &_
                 "&amount=" & Server.URLEncode(amount) &_
                 "&firstname=" & Server.URLEncode(name) &_
                 "&address1=" & Server.URLEncode(address) &_
                 "&zip=" & Server.URLEncode(zip)
    
        OGateway.Send DataToSend
    
        ResponseString = OGateway.responseText
        Results = Split(ResponseString, "&")
    
        GatewaySale = False
        For Each i in Results
            Result = Split(i,"=")
            If UBound(Result)>0 Then
                If  LCase(Result(0))="response" Then
                    If Result(1) = "1" Then
                        GatewaySale = True
                    End If
                End If
            End If
        Next
    End Function
    
    Results = GatewaySale("10.00","4111111111111111","0112","","John Smith","123 Main St", "60123")
    Response.Write("This should be true: " & Results & "")
    
    Results = GatewaySale("0.99","4111111111111111","0112","","John Smith","123 Main St", "60123")
    Response.Write("This should be false: " & Results & "")


    ///###########################################################
    ///#                                                         #
    ///#  D I S C L A I M E R                                    #
    ///#                                                         #
    ///#  WARNING: ANY USE BY YOU OF THE SAMPLE CODE PROVIDED    #
    ///#  IS AT YOUR OWN RISK.                                   #
    ///#                                                         #
    ///#  This code is provided "as is" without                  #
    ///#  warranty of any kind, either express or implied,       #
    ///#  including but not limited to the implied warranties    #
    ///#  of merchantability and/or fitness for a particular     #
    ///#  purpose.                                               #
    ///#                                                         #
    ///#                                                         #
    ///###########################################################
    
    
    ///###########################################################
    ///#                                                         #
    ///#  Direct Post Transaction Submission Methodology         #
    ///#                                                         #
    ///###########################################################
    ///#                                                         #
    ///#  1. You gather all the required transaction data on     #
    ///#  your secure web site.                                  #
    ///#                                                         #
    ///#  2. The transaction data gets submitted (via HTTPS      #
    ///#  POST) to the gateway as one long string, consisting    #
    ///#  of specific name/value pairs.                          #
    ///#                                                         #
    ///#  3. When performing the HTTPS POST operation, you       #
    ///#  remain on the same web page from which you've          #
    ///#  performed the operation.                               #
    ///#                                                         #
    ///#  4. The Gateway immediately returns a transaction       #
    ///#  response string to the same web page from which you    #
    ///#  have performed the HTTPS POST operation.               #
    ///#                                                         #
    ///#  5. You may then parse the response string and act      #
    ///#  upon certain response criteria, according to your      #
    ///#  business needs.                                        #
    ///#                                                         #
    ///#                                                         #
    ///###########################################################
    
    <%@ Import Namespace="System.Net" %>
    <%@ Import Namespace="System.IO" %>
    <script language="C#" runat="server">
    void Page_Load(Object Src, EventArgs E) {
    
    // Process readHtmlPage function
      myPage.Text = readHtmlPage("https://centavo.transactiongateway.com/api/transact.php");
    }
    
    
    
    private String readHtmlPage(string url)
    {
    
    //setup some variables
    
    String security_key = "6457Thfj624V5r7WUwc5v6a68Zsd6YEm";
    String firstname = "John";
    String lastname  = "Smith";
    String address1  = "1234 Main St.";
    String city      = "Chicago";
    String state     = "IL";
    String zip       = "60193";
    
    //setup some variables end
    
      String result = "";
      String strPost = "security_key=" + security_key
         + "&firstname=" + firstname + "&lastname=" + lastname
         + "&address1=" + address1 + "&city=" + city + "&state=" + state
         + "&zip=" + zip + "&payment=creditcard&type=sale"
         + "&amount=1.00&ccnumber=4111111111111111&ccexp=1015&cvv=123";
      StreamWriter myWriter = null;
    
      HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
      objRequest.Method = "POST";
      objRequest.ContentLength = strPost.Length;
      objRequest.ContentType = "application/x-www-form-urlencoded";
    
      try
      {
         myWriter = new StreamWriter(objRequest.GetRequestStream());
         myWriter.Write(strPost);
      }
      catch (Exception e)
      {
         return e.Message;
      }
      finally {
         myWriter.Close();
      }
    
      HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
      using (StreamReader sr =
         new StreamReader(objResponse.GetResponseStream()) )
      {
         result = sr.ReadToEnd();
    
         // Close and clean up the StreamReader
         sr.Close();
      }
      return result;
    }
    </script>
    <html>
    <body>
    <b>The content on this web page is the result of an HTTP POST operation to the Gateway, using the Direct Post method.<br>
    <br/>
    </b><hr/>
    <asp:literal id="myPage" runat="server"/>
    </body>
    </html>

ccon.cfm


    <CFLOCK Name="#session.sessionID#" timeout="10" Type ="Exclusive">
    <CFPARAM NAME="session.status" Default="none">
    <CFPARAM NAME="emsg" Default="A connection with the financial gateway failed.">
    <CFSET oid = ''>
    <CFSET em = 0>
    
    <CFIF not IsDefined('URL.ccinterim')>
    <CFSET em = 100>
    <CFELSEIF not IsDefined('session.store')>
    <CFSET em = 101>
    <CFELSEIF not session.active>
    <CFSET em = 102>
    <CFELSEIF not session.store>
    <CFSET em = 103>
    <CFELSEIF #session.retry# gt 2>
    <CFSET em = 400>
    </CFIF>
    <CFIF em gt 0>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLtoken#&em=#em#">
    </CFIF>
    
    <CFSET start = GetTickCount()>
    <CFPARAM NAME="result" DEFAULT="false">
    <CFPARAM NAME="com_error" DEFAULT="none">
    <CFPARAM NAME="session.redirect" Default="x">
    <CFPARAM NAME="session.status" Default="none">
    <CFPARAM NAME="theactioncode" Default="">
    <CFSET oid = session.ponumber>
    
    <!--- fix date for 4 digits only now 09/09--->
    <CFSET ccmonth = SpanExcluding(session.exprdate, '/')>
    <CFSET ccyear = Mid(session.exprdate, 4, 2)>
    <CFSET session.exprdate = '#ccmonth##ccyear#'>
    <!--- the session.cvv value is set to a form default in ccinterim --->
    
    <!--- the session order values come from paydirect and the cc values from ccinterim --->
    <!--- Tax(default=0), shipping(default=0), and PO Number provide Level II processing --->
    <CFHTTP url="https://centavo.transactiongateway.com/api/transact.php"
    method="POST" resolveurl="yes" throwonerror="yes"
    PATH="d:\html\users\cfxa2\zanaducom\html\Test\CardTech\" FILE="tempfile.txt">
    <CFHTTPPARAM type="FORMFIELD" name="security_key" value="#session.TRNSKEY#">
    <CFHTTPPARAM type="FORMFIELD" name="type" value="#session.TRNSTYPE#">
    <CFHTTPPARAM type="FORMFIELD" name="amount" value="#session.ustotal#">
    <CFHTTPPARAM type="FORMFIELD" name="ccnumber" value="#session.ccnumber#">
    <CFHTTPPARAM type="FORMFIELD" name="ccexp" value="#session.exprdate#">
    <CFHTTPPARAM type="FORMFIELD" name="address1" value="#session.ccaddress#">
    <CFHTTPPARAM type="FORMFIELD" name="zip" value="#session.cczip#">
    <CFHTTPPARAM type="FORMFIELD" name="orderid" value="#session.ponumber#">
    <CFHTTPPARAM type="FORMFIELD" name="cvv" value="#session.cvv#">
    <CFHTTPPARAM type="FORMFIELD" name="tax" value="#session.ustax#">
    <CFHTTPPARAM type="FORMFIELD" name="shipping" value="#session.usshipping#">
    <!---CFHTTPPARAM type="FORMFIELD" name="transactionid" value="#form.transid#"--->
    </CFHTTP>
    <!---CFSET result = cfhttp.filecontent would be the usual method of getting the
    stored reply;  however, when working in a shared server environment with ColdFusion,
    the user may not have authorization to access this storage area and instead will
    have to specify the full path within their domain for the file storage location
    and again specify the path for a file read action. With multiple domains in a
    sandbox environment, any of the domains can be used for saving the reply file.  On
    each transaction this file gets over written.--->
    <CFFILE ACTION="read"
    FILE="d:\html\users\cfxa2\zanaducom\html\Test\CardTech\tempfile.txt"
    VARIABLE="result">
    
    <CFIF IsDefined('result')>
    <!--- create array of names and then loop to populate a query structure
    called "crdck".  Map mynames to Island names for standardization. If
    this is a first time gateway setup, the mapping will not be necessary.  Simply
    parse the names and values.--->
    <CFSET mystring = result>
    <!--- CFSET mynames = "response,responsetext,authcode,transactionid,avsresponse,cvvresponse,orderid,type" --->
    <!--- create arrays from the strings --->
    <CFSET myarray = ListToArray(mystring, "&")>
    <CFSET islandnames = "ActionCode,Status,AuthNumber,MerchantTransaction,AVSCode,CVVcode,OrderID,Referencecode">
    <CFSET islandnamearray = ListToArray(islandnames, ",")>
    <!--- create a new array called crdck and then populate it in a loop with the Island
    names and the values.  This is done to remain compatible with previous
    instances of other gateways without having to change all of the downstream syntax. --->
    <CFSET crdck = QueryNew(islandnames)>
    <CFSET temp = QueryAddRow(crdck)>
    <!--- loop to populate array with desired names (island names) and values --->
    <CFLOOP  INDEX="k" FROM="1" TO="#ArrayLen(myarray)#">
    <CFSET sz = Len(myarray[k])>
    <CFSET m = FindNoCase("=", myarray[k], 1)>
    <CFIF m is 0><!--- create dummy value in case the = sign not found --->
    <CFSET temp = QuerySetCell(crdck, islandnamearray[k], "xxx")>
    <CFELSE>
    <CFSET n = Find("=", myarray[k], m+sz)>
    <CFSET avalue = Mid(myarray[k], m+1, sz)>
    <CFSET temp = QuerySetCell(crdck, islandnamearray[k], avalue)>
    </CFIF>
    <CFIF #k# gt 20><CFBREAK></CFIF><!--- prevent an endless loop for any reason --->
    </CFLOOP>
    </CFIF>
    
    <CFIF IsDefined('crdck.Actioncode')>
    <CFSET theactioncode = crdck.Actioncode>
    <!--- this call will timeout based on server configuration --->
    
    <CFSET thedate = DateFormat(now(), 'mm/dd/yy')>
    
    <!--- some mapping is required because CardTech gateway uses their Responsetext
    field, our STATUS field, for both status and error messages. --->
    
    <!--- In our database STATUS is a short advisory to the merchant on the order
    summary page.  Their 'response' is our actioncode--->
    <CFSET thestatus = crdck.Actioncode>
    <CFIF thestatus eq 1>
    <CFSET thestatus = 'auth-settle::1'>
    <CFELSEIF thestatus eq 2>
    <CFSET thestatus = 'retry-auth(credit)::2'>
    <CFELSEIF thestatus eq 3>
    <CFSET thestatus = 'retry-auth(data)::3'>
    <CFELSEIF thestatus eq "">
    <CFSET thestatus = 'retry-auth(comm)::'>
    </CFIF>
    
    <!--- A short statement for the 'trnsmsg' on the order detail page. CardTech
    returns 'success' in their responsetext field when actioncode=1 --->
    <CFSET msg = crdck.status>
    <CFIF crdck.Actioncode is not 1>
    <CFSET msg = 'declined'>
    </CFIF>
    
    <!--- CardTech Responsetext(our status) is a message which is mapped to our
    error message when 'success' (CardTech actioncode is not equal to 1)is not
    returned. The emsg(error message) is for the customer and order detail page. --->
    <CFSET emsg = crdck.status>
    <CFIF crdck.Actioncode is 1>
    <CFSET emsg = 'no-error'>
    </CFIF>
    
    <!--- zero lenth not allowed in database table entry --->
    <CFSET oid = crdck.OrderID>
    <CFIF #Len(oid)# is 0>
    <CFSET oid = #session.ponumber#>
    </CFIF>
    
    <CFSET avs = crdck.AVSCode>
    <CFIF Len(avs) is 0>
    <CFSET avs = 'no return'>
    </CFIF>
    
    <CFSET cvv = crdck.CVVCode>
    <CFIF Len(cvv) is 0>
    <CFSET cvv = 'no return'>
    </CFIF>
    
    <CFSET authnum = crdck.AuthNumber>
    <CFIF Len(authnum) is 0>
    <CFSET authnum = 'xxx'>
    </CFIF>
    
    <CFSET trnsmsg = '#authnum#::#msg#::#crdck.ActionCode#'>
    <CFSET trnsid = '#crdck.MerchantTransaction#::#crdck.ReferenceCode#'>
    
    <CFQUERY NAME="logpayment" DATASOURCE="#application.ordersDSN#">
        UPDATE #session.table#
        SET	TRNSMSG = '#trnsmsg#',<!--- this is RESULT entry on order detail page --->
            STATUS = '#thestatus#',
            AVS = '#avs#',
            TRNSRSV = '#cvv#',
            ERRORMSG = '#emsg#',
            TRANSID = '#trnsid#' <!--- this is Authorize ID on order detail page --->
            WHERE
            PONUMBER = '#oid#'
    </CFQUERY>
    
    <CFSET session.retry = session.retry +1>
    <CFSET end = GetTickCount()>
    <CFSET session.duration = evaluate((end - session.start)/1000)>
    
    <CFIF crdck.Actioncode is 1>
    <CFLOCATION URL = "../Templates/cc_good.cfm?#session.URLToken#&ccon=1">
    
    <CFELSEIF crdck.Actioncode is 2>
    <CFSET em = 401>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLToken#&em=#em#&emsg=#emsg#">
    
    <CFELSEIF crdck.ActionCode is 3 AND FindNoCase('expiration', emsg,1) gt 0>
    <CFSET em = 402>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLToken#&em=#em#&emsg=#emsg#">
    
    <CFELSEIF crdck.ActionCode is 3 AND FindNoCase('invalid', emsg,1) gt 0>
    <CFSET em = 405>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLToken#&em=#em#&emsg=#emsg#">
    
    <CFELSEIF crdck.ActionCode is 3>
    <CFSET em = 404>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLToken#&em=#em#&emsg=#emsg#">
    </CFIF>
    </CFIF><!--- end of crdck.actioncode defined --->
    
    <CFIF theactioncode is ""><!--- from the default value modified by crdck.actioncode --->
    <CFSET em = 406>
    <CFLOCATION URL="../Templates/process_error.cfm?#session.URLToken#&em=#em#&emsg=""">
    </CFIF>
    </CFLOCK>


    import java.util.*;
    import java.io.*;
    import java.net.*;
    import java.security.*;
    import java.text.*;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSession;
    
    class PaymentGateway {
    
        protected String server;
        protected String port;
        protected String path;
        protected String security_key;
    
        public PaymentGateway(String key)
        {
    
        server = "centavo.transactiongateway.com";
        port = "443";
        path = "https://centavo.transactiongateway.com/api/transact.php";
        security_key = key;
    
        }
    
        public HashMap doSale( double amount,
                                String ccNumber,
                                String ccExp
                                ) throws Exception
        {
            HashMap result = new HashMap();
            HashMap request = new HashMap();
    
            DecimalFormat form = new DecimalFormat("#.00");
    
            request.put("amount", form.format(amount));
            request.put("type", "sale");
            request.put("ccnumber", ccNumber);
            request.put("ccexp", ccExp);
    
            String data_out = prepareRequest(request);
    
            String error = "";
            String data_in = "";
            boolean success = true;
            try {
                HashMap retval = postForm(data_out);
                data_in = (String)retval.get("response");
                result.put("transactionid", retval.get("transactionid"));
            } catch (IOException e) {
                success = false;
                error = "Connect error, " + e.getMessage();
            } catch (Exception e) {
                success = false;
                error = e.getMessage();
            }
            if (!success) {
                throw new Exception(error);
            }
    
            return result;
        }
    
        // Utility Functions
    
        public String prepareRequest(HashMap request) {
    
            if (request.size() == 0) {
                return "";
            }
    
            request.put("security_key", security_key);
    
            Set s = request.keySet();
            Iterator i = s.iterator();
            Object key = i.next();
            StringBuffer buffer = new StringBuffer();
    
    
    
            buffer.append(key).append("=")
                .append(URLEncoder.encode((String) request.get(key)));
    
            while (i.hasNext()) {
                key = i.next();
                buffer.append("&").append(key).append("=")
                    .append(URLEncoder.encode((String) request.get(key)));
            }
    
            return buffer.toString();
    
        }
    
        protected HashMap postForm(String data) throws Exception {
    
            HashMap result = new HashMap();
    
            HttpURLConnection postConn;
    
            HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                return true;
            }
            };
    
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
    
            URL post = new URL("https", server, Integer.parseInt(port), path);
            postConn = (HttpURLConnection)post.openConnection();
    
            postConn.setRequestMethod("POST");
            postConn.setDoOutput(true);
    
            PrintWriter out = new PrintWriter(postConn.getOutputStream());
            out.print(data);
            out.close();
    
            BufferedReader in =
            new BufferedReader(new InputStreamReader(postConn.getInputStream()));
    
            String inputLine;
            StringBuffer buffer = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
            buffer.append(inputLine);
            }
            in.close();
    
    
            String response = buffer.toString();
    
            result.put("response", response);
    
            // Parse Result
            StringTokenizer st = new StringTokenizer(response, "&");
            while (st.hasMoreTokens()) {
            String varString = st.nextToken();
            StringTokenizer varSt = new StringTokenizer(varString, "=");
            if (varSt.countTokens() > 2 || varSt.countTokens()<1) {
                throw new Exception("Bad variable from processor center: " + varString);
            }
            if (varSt.countTokens()==1) {
                result.put(varSt.nextToken(), "");
            } else {
                result.put(varSt.nextToken(), varSt.nextToken());
            }
            }
    
            if (result.get("response")=="") {
            throw new Exception("Bad response from processor center" + response);
            }
    
            if (!result.get("response").toString().equals("1")) {
            throw new Exception(result.get("responsetext").toString());
            }
    
            return result;
        }
    
    }
    
    public class TestPaymentGateway
    {
        public static void main(String arg[])
        {
            HashMap retval = new HashMap();
            PaymentGateway gw = new PaymentGateway("6457Thfj624V5r7WUwc5v6a68Zsd6YEm");
    
            try {
                retval = gw.doSale(10.05, "4111111111111111", "0909");
                System.out.println("Success\nTransId: " + retval.get("transactionid") + "\n");
            } catch (Exception e) {
                System.out.println("Error: " + e.getMessage());
            }
    
        }
    }


    const https = require('https');
    const querystring = require('querystring');
    
    class DirectPost {
        constructor(security_key) {
        this.security_key = security_key;
        }
    
        setBilling(billingInformation) {
        // Validate that passed in information contains valid keys
        const validBillingKeys = ['first_name', 'last_name', 'company', 'address1',
            'address2', 'city', 'state', 'zip', 'country', 'phone', 'fax', 'email'];
    
        for (let key in billingInformation) {
            if (!validBillingKeys.includes(key)) {
            throw new Error(`Invalid key provided in billingInformation. '${key}'
                is not a valid billing parameter.`)
            }
        };
    
        this.billing = billingInformation;
        }
    
        setShipping(shippingInformation) {
        // Validate that passed in information contains valid keys
        const validShippingKeys = [
            'shipping_first_name', 'shipping_last_name', 'shipping_company',
            'shipping_address1', 'address2', 'shipping_city', 'shipping_state',
            'shipping_zip', 'shipping_country', 'shipping_email'
        ];
    
        for (let key in shippingInformation) {
            if (!validShippingKeys.includes(key)) {
            throw new Error(`Invalid key provided in shippingInformation. '${key}'
                is not a valid shipping parameter.`)
            }
        };
    
        this.shipping = shippingInformation;
        }
    
        doSale(amount, ccNum, ccExp, cvv) {
        let requestOptions = {
            'type': 'sale',
            'amount': amount,
            'ccnumber': ccNum,
            'ccexp': ccExp,
            'cvv': cvv
        };
    
        // Merge together all request options into one object
        Object.assign(requestOptions, this.billing, this.shipping);
    
        // Make request
        this._doRequest(requestOptions);
        }
    
        _doRequest(postData) {
        const hostName = 'centavo.transactiongateway.com';
        const path = '/api/transact.php';
    
        postData.security_key = this.security_key;
        postData = querystring.stringify(postData);
    
        const options = {
            hostname: hostName,
            path: path,
            method: 'POST',
            headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData)
            }
        };
    
        // Make request to Direct Post API
        const req = https.request(options, (response) => {
            console.log(`STATUS: ${response.statusCode}`);
            console.log(`HEADERS: ${JSON.stringify(response.headers)}`);
    
            response.on('data', (chunk) => {
            console.log(`BODY: ${chunk}`);
            });
            response.on('end', () => {
            console.log('No more data in response.');
            });
        });
    
        req.on('error', (e) => {
            console.error(`Problem with request: ${e.message}`);
        });
    
        // Write post data to request body
        req.write(postData);
        req.end();
        }
    }
    
    const dp = new DirectPost('{security_key}');
    const billingInfo = {
        'first_name': 'Test',
        'last_name': 'User',
        'address1': '123 Main St',
        'city': 'New York',
        'state': 'NY',
        'zip' : '12345',
    }
    const shippingInfo = {
        'shipping_first_name': 'User',
        'shipping_last_name': 'Test',
        'shipping_address1': '987 State St',
        'shipping_city': 'Los Angeles',
        'shipping_state': 'CA',
        'shipping_zip' : '98765',
    }
    
    dp.setBilling(billingInfo);
    dp.setShipping(shippingInfo);
    // Set dummy data for sale
    dp.doSale('100.00', '4111111111111111', '1221', '123');
    

    define("APPROVED", 1);
    define("DECLINED", 2);
    define("ERROR", 3);
    
    class gwapi {
    
    // Initial Setting Functions
    
        function setLogin($security_key) {
        $this->login['security_key'] = $security_key;
        }
    
        function setOrder($orderid,
            $orderdescription,
            $tax,
            $shipping,
            $ponumber,
            $ipaddress) {
        $this->order['orderid']          = $orderid;
        $this->order['orderdescription'] = $orderdescription;
        $this->order['tax']              = $tax;
        $this->order['shipping']         = $shipping;
        $this->order['ponumber']         = $ponumber;
        $this->order['ipaddress']        = $ipaddress;
        }
    
        function setBilling($firstname,
            $lastname,
            $company,
            $address1,
            $address2,
            $city,
            $state,
            $zip,
            $country,
            $phone,
            $fax,
            $email,
            $website) {
        $this->billing['firstname'] = $firstname;
        $this->billing['lastname']  = $lastname;
        $this->billing['company']   = $company;
        $this->billing['address1']  = $address1;
        $this->billing['address2']  = $address2;
        $this->billing['city']      = $city;
        $this->billing['state']     = $state;
        $this->billing['zip']       = $zip;
        $this->billing['country']   = $country;
        $this->billing['phone']     = $phone;
        $this->billing['fax']       = $fax;
        $this->billing['email']     = $email;
        $this->billing['website']   = $website;
        }
    
        function setShipping($firstname,
            $lastname,
            $company,
            $address1,
            $address2,
            $city,
            $state,
            $zip,
            $country,
            $email) {
        $this->shipping['firstname'] = $firstname;
        $this->shipping['lastname']  = $lastname;
        $this->shipping['company']   = $company;
        $this->shipping['address1']  = $address1;
        $this->shipping['address2']  = $address2;
        $this->shipping['city']      = $city;
        $this->shipping['state']     = $state;
        $this->shipping['zip']       = $zip;
        $this->shipping['country']   = $country;
        $this->shipping['email']     = $email;
        }
    
        // Transaction Functions
    
        function doSale($amount, $ccnumber, $ccexp, $cvv="") {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Sales Information
        $query .= "ccnumber=" . urlencode($ccnumber) . "&";
        $query .= "ccexp=" . urlencode($ccexp) . "&";
        $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        $query .= "cvv=" . urlencode($cvv) . "&";
        // Order Information
        $query .= "ipaddress=" . urlencode($this->order['ipaddress']) . "&";
        $query .= "orderid=" . urlencode($this->order['orderid']) . "&";
        $query .= "orderdescription=" . urlencode($this->order['orderdescription']) . "&";
        $query .= "tax=" . urlencode(number_format($this->order['tax'],2,".","")) . "&";
        $query .= "shipping=" . urlencode(number_format($this->order['shipping'],2,".","")) . "&";
        $query .= "ponumber=" . urlencode($this->order['ponumber']) . "&";
        // Billing Information
        $query .= "firstname=" . urlencode($this->billing['firstname']) . "&";
        $query .= "lastname=" . urlencode($this->billing['lastname']) . "&";
        $query .= "company=" . urlencode($this->billing['company']) . "&";
        $query .= "address1=" . urlencode($this->billing['address1']) . "&";
        $query .= "address2=" . urlencode($this->billing['address2']) . "&";
        $query .= "city=" . urlencode($this->billing['city']) . "&";
        $query .= "state=" . urlencode($this->billing['state']) . "&";
        $query .= "zip=" . urlencode($this->billing['zip']) . "&";
        $query .= "country=" . urlencode($this->billing['country']) . "&";
        $query .= "phone=" . urlencode($this->billing['phone']) . "&";
        $query .= "fax=" . urlencode($this->billing['fax']) . "&";
        $query .= "email=" . urlencode($this->billing['email']) . "&";
        $query .= "website=" . urlencode($this->billing['website']) . "&";
        // Shipping Information
        $query .= "shipping_firstname=" . urlencode($this->shipping['firstname']) . "&";
        $query .= "shipping_lastname=" . urlencode($this->shipping['lastname']) . "&";
        $query .= "shipping_company=" . urlencode($this->shipping['company']) . "&";
        $query .= "shipping_address1=" . urlencode($this->shipping['address1']) . "&";
        $query .= "shipping_address2=" . urlencode($this->shipping['address2']) . "&";
        $query .= "shipping_city=" . urlencode($this->shipping['city']) . "&";
        $query .= "shipping_state=" . urlencode($this->shipping['state']) . "&";
        $query .= "shipping_zip=" . urlencode($this->shipping['zip']) . "&";
        $query .= "shipping_country=" . urlencode($this->shipping['country']) . "&";
        $query .= "shipping_email=" . urlencode($this->shipping['email']) . "&";
        $query .= "type=sale";
        return $this->_doPost($query);
        }
    
        function doAuth($amount, $ccnumber, $ccexp, $cvv="") {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Sales Information
        $query .= "ccnumber=" . urlencode($ccnumber) . "&";
        $query .= "ccexp=" . urlencode($ccexp) . "&";
        $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        $query .= "cvv=" . urlencode($cvv) . "&";
        // Order Information
        $query .= "ipaddress=" . urlencode($this->order['ipaddress']) . "&";
        $query .= "orderid=" . urlencode($this->order['orderid']) . "&";
        $query .= "orderdescription=" . urlencode($this->order['orderdescription']) . "&";
        $query .= "tax=" . urlencode(number_format($this->order['tax'],2,".","")) . "&";
        $query .= "shipping=" . urlencode(number_format($this->order['shipping'],2,".","")) . "&";
        $query .= "ponumber=" . urlencode($this->order['ponumber']) . "&";
        // Billing Information
        $query .= "firstname=" . urlencode($this->billing['firstname']) . "&";
        $query .= "lastname=" . urlencode($this->billing['lastname']) . "&";
        $query .= "company=" . urlencode($this->billing['company']) . "&";
        $query .= "address1=" . urlencode($this->billing['address1']) . "&";
        $query .= "address2=" . urlencode($this->billing['address2']) . "&";
        $query .= "city=" . urlencode($this->billing['city']) . "&";
        $query .= "state=" . urlencode($this->billing['state']) . "&";
        $query .= "zip=" . urlencode($this->billing['zip']) . "&";
        $query .= "country=" . urlencode($this->billing['country']) . "&";
        $query .= "phone=" . urlencode($this->billing['phone']) . "&";
        $query .= "fax=" . urlencode($this->billing['fax']) . "&";
        $query .= "email=" . urlencode($this->billing['email']) . "&";
        $query .= "website=" . urlencode($this->billing['website']) . "&";
        // Shipping Information
        $query .= "shipping_firstname=" . urlencode($this->shipping['firstname']) . "&";
        $query .= "shipping_lastname=" . urlencode($this->shipping['lastname']) . "&";
        $query .= "shipping_company=" . urlencode($this->shipping['company']) . "&";
        $query .= "shipping_address1=" . urlencode($this->shipping['address1']) . "&";
        $query .= "shipping_address2=" . urlencode($this->shipping['address2']) . "&";
        $query .= "shipping_city=" . urlencode($this->shipping['city']) . "&";
        $query .= "shipping_state=" . urlencode($this->shipping['state']) . "&";
        $query .= "shipping_zip=" . urlencode($this->shipping['zip']) . "&";
        $query .= "shipping_country=" . urlencode($this->shipping['country']) . "&";
        $query .= "shipping_email=" . urlencode($this->shipping['email']) . "&";
        $query .= "type=auth";
        return $this->_doPost($query);
        }
    
        function doCredit($amount, $ccnumber, $ccexp) {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Sales Information
        $query .= "ccnumber=" . urlencode($ccnumber) . "&";
        $query .= "ccexp=" . urlencode($ccexp) . "&";
        $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        // Order Information
        $query .= "ipaddress=" . urlencode($this->order['ipaddress']) . "&";
        $query .= "orderid=" . urlencode($this->order['orderid']) . "&";
        $query .= "orderdescription=" . urlencode($this->order['orderdescription']) . "&";
        $query .= "tax=" . urlencode(number_format($this->order['tax'],2,".","")) . "&";
        $query .= "shipping=" . urlencode(number_format($this->order['shipping'],2,".","")) . "&";
        $query .= "ponumber=" . urlencode($this->order['ponumber']) . "&";
        // Billing Information
        $query .= "firstname=" . urlencode($this->billing['firstname']) . "&";
        $query .= "lastname=" . urlencode($this->billing['lastname']) . "&";
        $query .= "company=" . urlencode($this->billing['company']) . "&";
        $query .= "address1=" . urlencode($this->billing['address1']) . "&";
        $query .= "address2=" . urlencode($this->billing['address2']) . "&";
        $query .= "city=" . urlencode($this->billing['city']) . "&";
        $query .= "state=" . urlencode($this->billing['state']) . "&";
        $query .= "zip=" . urlencode($this->billing['zip']) . "&";
        $query .= "country=" . urlencode($this->billing['country']) . "&";
        $query .= "phone=" . urlencode($this->billing['phone']) . "&";
        $query .= "fax=" . urlencode($this->billing['fax']) . "&";
        $query .= "email=" . urlencode($this->billing['email']) . "&";
        $query .= "website=" . urlencode($this->billing['website']) . "&";
        $query .= "type=credit";
        return $this->_doPost($query);
        }
    
        function doOffline($authorizationcode, $amount, $ccnumber, $ccexp) {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Sales Information
        $query .= "ccnumber=" . urlencode($ccnumber) . "&";
        $query .= "ccexp=" . urlencode($ccexp) . "&";
        $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        $query .= "authorizationcode=" . urlencode($authorizationcode) . "&";
        // Order Information
        $query .= "ipaddress=" . urlencode($this->order['ipaddress']) . "&";
        $query .= "orderid=" . urlencode($this->order['orderid']) . "&";
        $query .= "orderdescription=" . urlencode($this->order['orderdescription']) . "&";
        $query .= "tax=" . urlencode(number_format($this->order['tax'],2,".","")) . "&";
        $query .= "shipping=" . urlencode(number_format($this->order['shipping'],2,".","")) . "&";
        $query .= "ponumber=" . urlencode($this->order['ponumber']) . "&";
        // Billing Information
        $query .= "firstname=" . urlencode($this->billing['firstname']) . "&";
        $query .= "lastname=" . urlencode($this->billing['lastname']) . "&";
        $query .= "company=" . urlencode($this->billing['company']) . "&";
        $query .= "address1=" . urlencode($this->billing['address1']) . "&";
        $query .= "address2=" . urlencode($this->billing['address2']) . "&";
        $query .= "city=" . urlencode($this->billing['city']) . "&";
        $query .= "state=" . urlencode($this->billing['state']) . "&";
        $query .= "zip=" . urlencode($this->billing['zip']) . "&";
        $query .= "country=" . urlencode($this->billing['country']) . "&";
        $query .= "phone=" . urlencode($this->billing['phone']) . "&";
        $query .= "fax=" . urlencode($this->billing['fax']) . "&";
        $query .= "email=" . urlencode($this->billing['email']) . "&";
        $query .= "website=" . urlencode($this->billing['website']) . "&";
        // Shipping Information
        $query .= "shipping_firstname=" . urlencode($this->shipping['firstname']) . "&";
        $query .= "shipping_lastname=" . urlencode($this->shipping['lastname']) . "&";
        $query .= "shipping_company=" . urlencode($this->shipping['company']) . "&";
        $query .= "shipping_address1=" . urlencode($this->shipping['address1']) . "&";
        $query .= "shipping_address2=" . urlencode($this->shipping['address2']) . "&";
        $query .= "shipping_city=" . urlencode($this->shipping['city']) . "&";
        $query .= "shipping_state=" . urlencode($this->shipping['state']) . "&";
        $query .= "shipping_zip=" . urlencode($this->shipping['zip']) . "&";
        $query .= "shipping_country=" . urlencode($this->shipping['country']) . "&";
        $query .= "shipping_email=" . urlencode($this->shipping['email']) . "&";
        $query .= "type=offline";
        return $this->_doPost($query);
        }
    
        function doCapture($transactionid, $amount =0) {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Transaction Information
        $query .= "transactionid=" . urlencode($transactionid) . "&";
        if ($amount>0) {
            $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        }
        $query .= "type=capture";
        return $this->_doPost($query);
        }
    
        function doVoid($transactionid) {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Transaction Information
        $query .= "transactionid=" . urlencode($transactionid) . "&";
        $query .= "type=void";
        return $this->_doPost($query);
        }
    
        function doRefund($transactionid, $amount = 0) {
    
        $query  = "";
        // Login Information
        $query .= "security_key=" . urlencode($this->login['security_key']) . "&";
        // Transaction Information
        $query .= "transactionid=" . urlencode($transactionid) . "&";
        if ($amount>0) {
            $query .= "amount=" . urlencode(number_format($amount,2,".","")) . "&";
        }
        $query .= "type=refund";
        return $this->_doPost($query);
        }
    
        function _doPost($query) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://centavo.transactiongateway.com/api/transact.php");
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    
        curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
        curl_setopt($ch, CURLOPT_POST, 1);
    
        if (!($data = curl_exec($ch))) {
            return ERROR;
        }
        curl_close($ch);
        unset($ch);
        print "\n$data\n";
        $data = explode("&",$data);
        for($i=0;$i<count($data);$i++) {
            $rdata = explode("=",$data[$i]);
            $this->responses[$rdata[0]] = $rdata[1];
        }
        return $this->responses['response'];
        }
    }
    
    $gw = new gwapi;
    $gw->setLogin("6457Thfj624V5r7WUwc5v6a68Zsd6YEm");
    $gw->setBilling("John","Smith","Acme, Inc.","123 Main St","Suite 200", "Beverly Hills",
            "CA","90210","US","555-555-5555","555-555-5556","support@example.com",
            "www.example.com");
    $gw->setShipping("Mary","Smith","na","124 Shipping Main St","Suite Ship", "Beverly Hills",
            "CA","90210","US","support@example.com");
    $gw->setOrder("1234","Big Order",1, 2, "PO1234","65.192.14.10");
    
    $r = $gw->doSale("50.00","4111111111111111","1010");
    print $gw->responses['responsetext'];
    

    ###########################################################
    #                                                         #
    #  D I S C L A I M E R                                    #
    #                                                         #
    #  WARNING: ANY USE BY YOU OF THE SAMPLE CODE PROVIDED    #
    #  IS AT YOUR OWN RISK.                                   #
    #                                                         #
    #  The code is  provided  "as is" without                 #
    #  warranty of any kind, either express or implied,       #
    #  including but not limited to the implied warranties    #
    #  of merchantability and/or fitness for a particular     #
    #  purpose.                                               #
    #                                                         #
    #                                                         #
    ###########################################################
    
    
    
    import pycurl
    import urllib
    import urlparse
    import StringIO
    
    
    class gwapi():
    
        def __init__(self):
            self.login= dict()
            self.order = dict()
            self.billing = dict()
            self.shipping = dict()
            self.responses = dict()
    
        def setLogin(self,security_key):
            self.login['security_key'] = security_key
    
        def setOrder(self, orderid, orderdescription, tax, shipping, ponumber,ipadress):
            self.order['orderid'] = orderid;
            self.order['orderdescription'] = orderdescription
            self.order['shipping'] = '{0:.2f}'.format(float(shipping))
            self.order['ipaddress'] = ipadress
            self.order['tax'] = '{0:.2f}'.format(float(tax))
            self.order['ponumber'] = ponumber
    
    
        def setBilling(self,
                firstname,
                lastname,
                company,
                address1,
                address2,
                city,
                state,
                zip,
                country,
                phone,
                fax,
                email,
                website):
            self.billing['firstname'] = firstname
            self.billing['lastname']  = lastname
            self.billing['company']   = company
            self.billing['address1']  = address1
            self.billing['address2']  = address2
            self.billing['city']      = city
            self.billing['state']     = state
            self.billing['zip']       = zip
            self.billing['country']   = country
            self.billing['phone']     = phone
            self.billing['fax']       = fax
            self.billing['email']     = email
            self.billing['website']   = website
    
        def setShipping(self,firstname,
                lastname,
                company,
                address1,
                address2,
                city,
                state,
                zipcode,
                country,
                email):
            self.shipping['firstname'] = firstname
            self.shipping['lastname']  = lastname
            self.shipping['company']   = company
            self.shipping['address1']  = address1
            self.shipping['address2']  = address2
            self.shipping['city']      = city
            self.shipping['state']     = state
            self.shipping['zip']       = zipcode
            self.shipping['country']   = country
            self.shipping['email']     = email
    
    
        def doSale(self,amount, ccnumber, ccexp, cvv=''):
    
            query  = ""
            # Login Information
    
            query = query + "security_key=" + urllib.quote(self.login['security_key']) + "&"
            # Sales Information
            query += "ccnumber=" + urllib.quote(ccnumber) + "&"
            query += "ccexp=" + urllib.quote(ccexp) + "&"
            query += "amount=" + urllib.quote('{0:.2f}'.format(float(amount))) + "&"
            if (cvv!=''):
                query += "cvv=" + urllib.quote(cvv) + "&"
            # Order Information
            for key,value in self.order.iteritems():
                query += key +"=" + urllib.quote(str(value)) + "&"
    
            # Billing Information
            for key,value in self.billing.iteritems():
                query += key +"=" + urllib.quote(str(value)) + "&"
    
            # Shipping Information
            for key,value in self.shipping.iteritems():
                query += key +"=" + urllib.quote(str(value)) + "&"
    
            query += "type=sale"
            return self.doPost(query)
    
    
    
        def doPost(self,query):
            responseIO = StringIO.StringIO()
            curlObj = pycurl.Curl()
            curlObj.setopt(pycurl.POST,1)
            curlObj.setopt(pycurl.CONNECTTIMEOUT,30)
            curlObj.setopt(pycurl.TIMEOUT,30)
            curlObj.setopt(pycurl.HEADER,0)
            curlObj.setopt(pycurl.SSL_VERIFYPEER,0)
            curlObj.setopt(pycurl.WRITEFUNCTION,responseIO.write);
    
            curlObj.setopt(pycurl.URL,"https://centavo.transactiongateway.com/api/transact.php")
    
            curlObj.setopt(pycurl.POSTFIELDS,query)
    
            curlObj.perform()
    
            data = responseIO.getvalue()
            temp = urlparse.parse_qs(data)
            for key,value in temp.iteritems():
                self.responses[key] = value[0]
            return self.responses['response']
    
    # NOTE: your security_key should replace the one below
    gw = gwapi()
    gw.setLogin("6457Thfj624V5r7WUwc5v6a68Zsd6YEm");
    
    gw.setBilling("John","Smith","Acme, Inc.","123 Main St","Suite 200", "Beverly Hills",
            "CA","90210","US","555-555-5555","555-555-5556","support@example.com",
            "www.example.com")
    gw.setShipping("Mary","Smith","na","124 Shipping Main St","Suite Ship", "Beverly Hills",
            "CA","90210","US","support@example.com")
    gw.setOrder("1234","Big Order",1, 2, "PO1234","65.192.14.10")
    
    r = gw.doSale("5.00","4111111111111111","1212",'999')
    print gw.responses['response']
    
    if (int(gw.responses['response']) == 1) :
        print "Approved"
    elif (int(gw.responses['response']) == 2) :
        print "Declined"
    elif (int(gw.responses['response']) == 3) :
        print "Error"
    
    

    ###########################################################
    #                                                         #
    #  D I S C L A I M E R                                    #
    #                                                         #
    #  WARNING: ANY USE BY YOU OF THE SAMPLE CODE PROVIDED    #
    #  IS AT YOUR OWN RISK.                                   #
    #                                                         #
    #  The code is  provided  "as is" without                 #
    #  warranty of any kind, either express or implied,       #
    #  including but not limited to the implied warranties    #
    #  of merchantability and/or fitness for a particular     #
    #  purpose.                                               #
    #                                                         #
    #                                                         #
    ###########################################################
    
    
    
    require 'rubygems'
    require 'curb'
    require 'uri'
    require 'addressable/uri'
    
    
    
    class GwApi
    
        def initialize()
            @login = {}
            @order = {}
            @billing = {}
            @shipping = {}
            @responses = {}
        end
    
        def setLogin(security_key)
            @login['security_key'] = security_key
        end
    
        def setOrder( orderid, orderdescription, tax, shipping, ponumber,ipadress)
            @order['orderid'] = orderid;
            @order['orderdescription'] = orderdescription
            @order['shipping'] = "%.2f" % shipping
            @order['ipaddress'] = ipadress
            @order['tax'] = "%.2f" % tax
            @order['ponumber'] = ponumber
        end
    
        def setBilling(
                firstname,
                lastname,
                company,
                address1,
                address2,
                city,
                state,
                zip,
                country,
                phone,
                fax,
                email,
                website)
            @billing['firstname'] = firstname
            @billing['lastname']  = lastname
            @billing['company']   = company
            @billing['address1']  = address1
            @billing['address2']  = address2
            @billing['city']      = city
            @billing['state']     = state
            @billing['zip']       = zip
            @billing['country']   = country
            @billing['phone']     = phone
            @billing['fax']       = fax
            @billing['email']     = email
            @billing['website']   = website
        end
    
        def setShipping(firstname,
                lastname,
                company,
                address1,
                address2,
                city,
                state,
                zipcode,
                country,
                email)
            @shipping['firstname'] = firstname
            @shipping['lastname']  = lastname
            @shipping['company']   = company
            @shipping['address1']  = address1
            @shipping['address2']  = address2
            @shipping['city']      = city
            @shipping['state']     = state
            @shipping['zip']       = zipcode
            @shipping['country']   = country
            @shipping['email']     = email
    
        end
    
        def doSale(amount, ccnumber, ccexp, cvv='')
    
            query  = ""
            # Login Information
    
            query = query + "security_key=" + URI.escape(@login['security_key']) + "&"
            # Sales Information
            query += "ccnumber=" + URI.escape(ccnumber) + "&"
            query += "ccexp=" + URI.escape(ccexp) + "&"
            query += "amount=" + URI.escape("%.2f" %amount) + "&"
            if (cvv!='')
                query += "cvv=" + URI.escape(cvv) + "&"
            end
    
            # Order Information
            @order.each do | key,value|
                query += key +"=" + URI.escape(value) + "&"
            end
    
            # Billing Information
            @billing.each do | key,value|
                query += key +"=" + URI.escape(value) + "&"
            end
            # Shipping Information
    
            @shipping.each do | key,value|
                query += key +"=" + URI.escape(value) + "&"
            end
    
            query += "type=sale"
            return doPost(query)
        end
    
    
        def doPost(query)
    
    
            curlObj = Curl::Easy.new("https://centavo.transactiongateway.com/api/transact.php")
            curlObj.connect_timeout = 30
            curlObj.timeout = 30
            curlObj.header_in_body = false
            curlObj.ssl_verify_peer=false
            curlObj.post_body = query
            curlObj.perform()
            data = curlObj.body_str
    
            # NOTE: The domain name below is simply used to create a full URI to allow URI.parse to parse out the query values
            # for us. It is not used to send any data
            data = '"https://centavo.transactiongateway.com/api/transact.php?' + data
            uri = Addressable::URI.parse(data)
            @responses = uri.query_values
            return @responses['response']
        end
    
        def getResponses()
            return @responses
        end
    end
    
    gw = GwApi.new()
    # NOTE: your security_key should replace the one below
    gw.setLogin("6457Thfj624V5r7WUwc5v6a68Zsd6YEm");
    
    gw.setBilling("John","Smith","Acme, Inc.","123 Main St","Suite 200", "Beverly Hills",
            "CA","90210","US","555-555-5555","555-555-5556","support@example.com",
            "www.example.com")
    
    gw.setShipping("Mary","Smith","na","124 Shipping Main St","Suite Ship", "Beverly Hills",
            "CA","90210","US","support@example.com")
    
    gw.setOrder("1234","Big Order",1, 2, "PO1234","65.192.14.10")
    
    r = gw.doSale("5.00","4111111111111111","1212",'999')
    myResponses = gw.getResponses
    
    print myResponses['response'] + "  "
    
    if (myResponses['response'] == '1')
        print "Approved \n"
    elsif (myResponses['response'] == '2')
        print "Declined \n"
    elsif (myResponses['response'] == '3')
        print "Error \n"
    end
    

Collect.js

Overview

Collect.js is a JavaScript framework that allows merchants to collect sensitive payment information from their customers without exposing their website to the sensitive information. This can be done while allowing merchants to retain full control over the look and feel of their checkout experience.

This is a data collection and tokenization system, not a full payments API, so you can use this in conjunction with an existing transaction API (Direct Post) to submit transactions or use other gateway services that utilize payment information.

Usage

Collect.js is designed to be flexible, and its implementation can be as simple as pasting a single script tag to your checkout page, or it can be customized to interact with your website however you’d like.

Authentication

Authentication is done via a “tokenization key” that you can generate in your merchant control panel under the “Security Keys” settings page. Select a public key, and then “Tokenization” for the key permissions.

This tokenization key can only be used with Collect.js and will not work with any other APIs. Similarly, any API keys already created will not work with Collect.js.

This key will be visible to customers in your website’s source code, so please make sure you only use the tokenization key here.

Public Security Keys



The Payment Token

This is a new variable added to the Direct Post API that should be used in conjunction with this tool. This is what Collect.js will return to your website and it takes the place of the sensitive card or bank account information. It will look something like this:

3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8

This variable can be used in place of the existing ccnumber, ccexp, and cvv variables we have today. For ACH transactions (details below) it can be used in place of checkname, checkaba, and checkaccount.

The payment token can only be used once, and will expire after 24 hours if it is not used at all.

The payment token will also work when adding customers to the Customer Vault or recurring subscriptions. Just use “payment_token” where you were using the credit card and ACH account information before.

For example, if you would previously send this string:

type=sale&amount=3.00&ccnumber=4111111111111111&ccexp=1020&cvv=123

Or

type=sale&amount=3.00&checkname=Jane Doe&checkaba=123123123&checkaccount=123123123

You could now send this:

type=sale&amount=3.00&payment_token=3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8
Test Token

If you would like to test using the payment token without using Collect.js to create one, you can use the below tokens to return test credit card and bank account information.

Payment Token Value Test Data
00000000-000000-000000-000000000000 Card: 4111111111111111, Expiration: October 2025, CVV: 999
11111111-111111-111111-111111111111 ABA: 123123123, Account: 123123123, Name: Jane Doe


Simple Lightbox Example


<html>
    <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
    <body>
        <h1>CollectJS Payment Form</h1>
        <form action="/your-page.php" method="post">
            <table>
                <tr>
                    <td>First Name</td>
                    <td><input size="30" type="text" name="fname" value="Test" /></td>
                </tr>
                <tr>
                    <td>Last Name</td>
                    <td><input size="30" type="text" name="lname" value="User" /></td>
                </tr>
                <tr>
                    <td>Address</td>
                    <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                </tr>
                <tr>
                    <td>City</td>
                    <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                </tr>
                <tr>
                    <td>State</td>
                    <td><input size="30" type="text" name="state" value="CA"></td>
                </tr>
                <tr>
                    <td>Zip</td>
                    <td><input size="30" type="text" name="zip" value="90210"></td>
                </tr>
                <tr>
                    <td>Country</td>
                    <td><input size="30" type="text" name="country" value="US"></td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td><input size="30" type="text" name="phone" value="5555555555"></td>
                </tr>
            </table>
            <br>
            <button id="payButton" type="button">Submit Payment</button>
        </form>
    </body>
</html>

Advanced HTML Lightbox Example


    <html>
        <head>
            <script
                src="https://centavo.transactiongateway.com/token/Collect.js"
                data-tokenization-key="your-token-key-here"
                data-payment-selector=".customPayButton"
                data-theme="bootstrap"
                data-primary-color="#ff288d"
                data-secondary-color="#ffe200"
                data-button-text="SUBMIT ME!"
                data-payment-type="cc"
                data-field-cvv-display="hide"
                data-instruction-text="Enter Card Information"
                data-price="1.00"
                data-currency="USD"
                data-country="US"
                data-field-google-pay-shipping-address-required="true"
                data-field-google-pay-shipping-address-parameters-phone-number-required="true"
                data-field-google-pay-shipping-address-parameters-allowed-country-codes="US,CA"
                data-field-google-pay-billing-address-required="true"
                data-field-google-pay-billing-address-parameters-phone-number-required="true"
                data-field-google-pay-billing-address-parameters-format="MIN"
                data-field-google-pay-email-required="true"
            ></script>
        </head>
        <body>
            <h1>CollectJS Payment Form</h1>
            <form action="/your-page.php" method="post">
                <table>
                    <tr>
                        <td>First Name</td>
                        <td><input size="30" type="text" name="fname" value="Test" /></td>
                    </tr>
                    <tr>
                        <td>Last Name</td>
                        <td><input size="30" type="text" name="lname" value="User" /></td>
                    </tr>
                    <tr>
                        <td>Address</td>
                        <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                    </tr>
                    <tr>
                        <td>City</td>
                        <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                    </tr>
                    <tr>
                        <td>State</td>
                        <td><input size="30" type="text" name="state" value="CA"></td>
                    </tr>
                    <tr>
                        <td>Zip</td>
                        <td><input size="30" type="text" name="zip" value="90210"></td>
                    </tr>
                    <tr>
                        <td>Country</td>
                        <td><input size="30" type="text" name="country" value="US"></td>
                    </tr>
                    <tr>
                        <td>Phone</td>
                        <td><input size="30" type="text" name="phone" value="5555555555"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td>
                            <div id="googlepaybutton"></div>
                        </td>
                    </tr>
    
                </table>
                <br>
                <button class="customPayButton" type="button">Pay the money.</button>
            </form>
        </body>
    </html>

Advanced JavaScript Lightbox Example


<html>
    <head>
        <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
        <script>
            document.addEventListener('DOMContentLoaded', function () {
                CollectJS.configure({
                    'paymentSelector' : '#customPayButton',
                    'theme': 'bootstrap',
                    'primaryColor': '#ff288d',
                    'secondaryColor': '#ffe200',
                    'buttonText': 'SUBMIT ME!',
                    'instructionText': 'Enter Card Info Below',
                    'paymentType': 'cc',
                    'fields': {
                            'cvv': {
                                'display':'hide'
                            },
                            'googlePay': {
                                'selector': '.googlePayButton',
                                'shippingAddressRequired': true,
                                'shippingAddressParameters': {
                                    'phoneNumberRequired': true,
                                    'allowedCountryCodes': ['US', 'CA']
                                },
                                'billingAddressRequired': true,
                                'billingAddressParameters': {
                                    'phoneNumberRequired': true,
                                    'format': 'MIN'
                                },
                                'emailRequired': true
                        }
                    },
                    'price': '1.00',
                    'currency':'USD',
                    'country': 'US',
                    'callback' : function(response) {
                        alert(response.token);
                        var input = document.createElement("input");
                        input.type = "hidden";
                        input.name = "payment_token";
                        input.value = response.token;
                        var form = document.getElementsByTagName("form")[0];
                        form.appendChild(input);
                        form.submit();
                    }
                });
            });
        </script>
    </head>
    <body>
        <h1>CollectJS Payment Form</h1>
        <form action="/your-page.php" method="post">
            <table>
                <tr>
                    <td>First Name</td>
                    <td><input size="30" type="text" name="fname" value="Test" /></td>
                </tr>
                <tr>
                    <td>Last Name</td>
                    <td><input size="30" type="text" name="lname" value="User" /></td>
                </tr>
                <tr>
                    <td>Address</td>
                    <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                </tr>
                <tr>
                    <td>City</td>
                    <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                </tr>
                <tr>
                    <td>State</td>
                    <td><input size="30" type="text" name="state" value="CA"></td>
                </tr>
                <tr>
                    <td>Zip</td>
                    <td><input size="30" type="text" name="zip" value="90210"></td>
                </tr>
                <tr>
                    <td>Country</td>
                    <td><input size="30" type="text" name="country" value="US"></td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td><input size="30" type="text" name="phone" value="5555555555"></td>
                </tr>
                <tr>
                    <td></td>
                    <td>
                        <div class="googlePayButton">
                    </td>
                </tr>
            </table>
            <br>
            <button id="customPayButton" type="button">Submit Payment</button>
        </form>
    </body>
</html>

Expert Lightbox Example


<html>
    <head>
        <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
        <script>
            document.addEventListener('DOMContentLoaded', function () {
                CollectJS.configure({
                    'paymentSelector' : '#customPayButton',
                    'theme': 'bootstrap',
                    'primaryColor': '#ff288d',
                    'secondaryColor': '#ffe200',
                    'buttonText': 'SUBMIT ME!',
                    'paymentType': 'cc',
                    'fields': {
                        'cvv': {
                            'display': 'hide'
                        },
                        'googlePay': {
                            'selector': '.googlePayButton',
                            'shippingAddressRequired': true,
                            'shippingAddressParameters': {
                                'phoneNumberRequired': true,
                                'allowedCountryCodes': ['US', 'CA']
                            },
                            'billingAddressRequired': true,
                            'billingAddressParameters': {
                                'phoneNumberRequired': true,
                                'format': 'MIN'
                            },
                            'emailRequired': true
                        }
                    },
                    "price": "1.00",
                    "currency":"USD",
                    "country": "US",
                    'callback' : function(response) {
                        alert(response.token);
                        var input = document.createElement("input");
                        input.type = "hidden";
                        input.name = "payment_token";
                        input.value = response.token;
                        var form = document.getElementsByTagName("form")[0];
                        form.appendChild(input);
                        form.submit();
                    }
                });
            });
        </script>
    </head>
    <body>
        <h1>CollectJS Payment Form</h1>
        <form action="/your-page.php" method="post">
            <table>
                <tr>
                    <td>First Name</td>
                    <td><input size="30" type="text" name="fname" value="Test" /></td>
                </tr>
                <tr>
                    <td>Last Name</td>
                    <td><input size="30" type="text" name="lname" value="User" /></td>
                </tr>
                <tr>
                    <td>Address</td>
                    <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                </tr>
                <tr>
                    <td>City</td>
                    <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                </tr>
                <tr>
                    <td>State</td>
                    <td><input size="30" type="text" name="state" value="CA"></td>
                </tr>
                <tr>
                    <td>Zip</td>
                    <td><input size="30" type="text" name="zip" value="90210"></td>
                </tr>
                <tr>
                    <td>Country</td>
                    <td><input size="30" type="text" name="country" value="US"></td>
                </tr>
                <tr>
                    <td>Phone</td>
                    <td><input size="30" type="text" name="phone" value="5555555555"></td>
                </tr>
                <tr>
                    <td></td>
                    <td>
                        <div class="googlePayButton">
                    </td>
                </tr>

            </table>
            <br>
                    To show the ability to trigger the form without a click, it will appear automatically after 5 seconds and disappear after another 5.
            <script>
                setTimeout("CollectJS.startPaymentRequest()", 5000);
                setTimeout("CollectJS.closePaymentRequest()", 10000);
            </script>
        </form>
    </body>
</html>

Simple Inline Example


    <html>
        <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here" data-variant="inline"></script>
        <body>
            <h1>CollectJS Payment Form</h1>
            <form action="/your-page.php" method="post">
                <table>
                    <tr>
                        <td>First Name</td>
                        <td><input size="30" type="text" name="fname" value="Test" /></td>
                    </tr>
                    <tr>
                        <td>Last Name</td>
                        <td><input size="30" type="text" name="lname" value="User" /></td>
                    </tr>
                    <tr>
                        <td>Address</td>
                        <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                    </tr>
                    <tr>
                        <td>City</td>
                        <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                    </tr>
                    <tr>
                        <td>State</td>
                        <td><input size="30" type="text" name="state" value="CA"></td>
                    </tr>
                    <tr>
                        <td>Zip</td>
                        <td><input size="30" type="text" name="zip" value="90210"></td>
                    </tr>
                    <tr>
                        <td>Country</td>
                        <td><input size="30" type="text" name="country" value="US"></td>
                    </tr>
                    <tr>
                        <td>Phone</td>
                        <td><input size="30" type="text" name="phone" value="5555555555"></td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            Credit Card Information
                        </td>
                    </tr>
                    <tr>
                        <td>CC Number</td>
                        <td id="ccnumber"></td>
                    </tr>
                    <tr>
                        <td>CC Exp</td>
                        <td id="ccexp"></td>
                    </tr>
                    <tr>
                        <td>CVV</td>
                        <td id="cvv"></td>
                    </tr>
                    <tr>
                        <td colspan="2">
                            Electronic Check Information
                        </td>
                    </tr>
                    <tr>
                        <td>Account Number</td>
                        <td id="checkaccount"></td>
                    </tr>
                    <tr>
                        <td>Routing Number</td>
                        <td id="checkaba"></td>
                    </tr>
                    <tr>
                        <td>Account Owner's Name</td>
                        <td id="checkname"></td>
                    </tr>
                </table>
                <br>
                <button id="payButton" type="button">Submit Payment</button>
            </form>
        </body>
    </html>

Advanced HTML Inline Example


    <html>
        <head>
            <script
                src="https://centavo.transactiongateway.com/token/Collect.js"
                data-tokenization-key="your-token-key-here"
                data-payment-selector="#demoPayButton"
                data-variant="inline"
                data-style-sniffer="false"
                data-google-font="Montserrat:400"
                data-validation-callback = "(function (field, valid, message) {console.log(field + ': ' + valid + ' -- ' + message)})"
                data-custom-css='{
                    "background-color": "#a0a0ff",
                    "color": "#0000ff"
                    }'
                data-invalid-css='{
                    "background-color":"red",
                    "color":"white"
                    }'
                data-valid-css='{
                    "background-color":"#d0ffd0",
                    "color":"black"
                    }'
                data-placeholder-css='{
                    "background-color":"#808080",
                    "color":"green"
                }'
                data-focus-css='{
                    "background-color":"#202020",
                    "color":"yellow"
                }'
                data-timeout-duration = "2000"
                data-timeout-callback = "(function() {console.log('Timeout reached')})"
                data-fields-available-callback = "(function() {console.log('Collect.js has added fields to the form')})"
                data-field-cvv-display = 'required'
                    data-field-ccnumber-selector = '#demoCcnumber'
                data-field-ccnumber-title = 'Card Number'
                data-field-ccnumber-placeholder = '0000 0000 0000 0000'
                data-field-ccexp-selector = '#demoCcexp'
                data-field-ccexp-title = 'Expiration Date'
                data-field-ccexp-placeholder = '00 / 00'
                data-field-cvv-display = 'required'
                data-field-cvv-selector = '#demoCvv'
                data-field-cvv-title = 'CVV Code'
                data-field-cvv-placeholder = '***'
                data-field-checkaccount-selector = '#demoCheckaccount'
                data-field-checkaccount-title = 'Account Number'
                data-field-checkaccount-placeholder = '000000000000'
                data-field-checkaba-selector = '#demoCheckaba'
                data-field-checkaba-title = 'Routing Number'
                data-field-checkaba-placeholder = '000000000'
                data-field-checkname-selector = '#demoCheckname'
                data-field-checkname-title = 'Account Name'
                data-field-checkname-placeholder = 'Customer Name'
                data-price="1.00"
                data-currency="USD"
                data-country="US"
                data-field-google-pay-shipping-address-required="true"
                data-field-google-pay-shipping-address-parameters-phone-number-required="true"
                data-field-google-pay-shipping-address-parameters-allowed-country-codes="US,CA"
                data-field-google-pay-billing-address-required="true"
                data-field-google-pay-billing-address-parameters-phone-number-required="true"
                data-field-google-pay-billing-address-parameters-format="MIN"
                data-field-google-pay-email-required="true"
            ></script>
            <!-- This style will be inherited by the style-sniffer, with the additions in the configuration -->
            <style>
                input {
                    border: 5px inset #808080;
                    background-color: #c0c0c0;
                    color: green;
                    font-size: 25px;
                    font-family: monospace;
                    padding: 5px;
                }
            </style>
        </head>
        <body>
            <h1>CollectJS Payment Form</h1>
            <form action="/your-page.php" method="post">
                <table>
                    <tr>
                        <td>Amount: </td>
                        <td><input size="50" type="text" name="amount" value="1.00" /></td>
                    </tr>
                    <tr>
                        <td>First Name: </td>
                        <td><input size="50" type="text" name="first_name" value="Test" /></td>
                    </tr>
                    <tr>
                        <td>Last Name: </td>
                        <td><input size="50" type="text" name="last_name" value="User" /></td>
                    </tr>
                    <tr>
                        <td>Address1</td>
                        <td><input size="50" type="text" name="address1" value="123 Main Street"></td>
                    </tr>
                    <tr>
                        <td>City</td>
                        <td><input size="50" type="text" name="city" value="Beverley Hills"></td>
                    </tr>
                    <tr>
                        <td>State</td>
                        <td><input size="50" type="text" name="state" value="CA"></td>
                    </tr>
                    <tr>
                        <td>zip</td>
                        <td><input size="50" type="text" name="zip" value="90210"></td>
                    </tr>
                    <tr>
                        <td>country</td>
                        <td><input size="50" type="text" name="country" value="US"></td>
                    </tr>
                    <tr>
                        <td>phone</td>
                        <td><input size="50" type="text" name="phone" value="5555555555"></td>
                    </tr>
                    <tr>
                        <td>CC Number</td>
                        <td id="demoCcnumber"></td>
                    </tr>
                    <tr>
                        <td>CC Exp</td>
                        <td id="demoCcexp"></td>
                    </tr>
                    <tr>
                        <td>CVV</td>
                        <td id="demoCvv"></td>
                    </tr>
                    <tr>
                        <td>Account Number</td>
                        <td id="demoCheckaccount"></td>
                    </tr>
                    <tr>
                        <td>Routing Number</td>
                        <td id="demoCheckaba"></td>
                    </tr>
                    <tr>
                        <td>Name on Account</td>
                        <td id="demoCheckname"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td>
                            <div id="googlepaybutton"></div>
                        </td>
                    </tr>
                </table>
                <br>
                <button id="demoPayButton" type="button">Pay the money.</button>
            </form>
        </body>
    </html>    

Advanced JavaScript Inline Example


    <html>
        <head>
            <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
            <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, shrink-to-fit=no">
            <style>
                input {
                    border: 5px inset #808080;
                    background-color: #c0c0c0;
                    color: green;
                    font-size: 25px;
                    font-family: monospace;
                    padding: 5px;
                }
            </style>
        </head>
        <body>
            <h1>Inline CollectJS Demo</h1>
            <form action="/your-page.php" method="post">
                <table>
                    <tr>
                        <td>Amount: </td>
                        <td><input size="50" type="text" name="amount" value="1.00" /></td>
                    </tr>
                    <tr>
                        <td>First Name: </td>
                        <td><input size="50" type="text" name="first_name" value="Test" /></td>
                    </tr>
                    <tr>
                        <td>Last Name: </td>
                        <td><input size="50" type="text" name="last_name" value="User" /></td>
                    </tr>
                    <tr>
                        <td>Address1</td>
                        <td><input size="50" type="text" name="address1" value="123 Main Street"></td>
                    </tr>
                    <tr>
                        <td>City</td>
                        <td><input size="50" type="text" name="city" value="Beverley Hills"></td>
                    </tr>
                    <tr>
                        <td>State</td>
                        <td><input size="50" type="text" name="state" value="CA"></td>
                    </tr>
                    <tr>
                        <td>zip</td>
                        <td><input size="50" type="text" name="zip" value="90210"></td>
                    </tr>
                    <tr>
                        <td>country</td>
                        <td><input size="50" type="text" name="country" value="US"></td>
                    </tr>
                    <tr>
                        <td>phone</td>
                        <td><input size="50" type="text" name="phone" value="5555555555"></td>
                    </tr>
                    <tr>
                        <td>CC Number</td>
                        <td id="demoCcnumber"></td>
                    </tr>
                    <tr>
                        <td>CC Exp</td>
                        <td id="demoCcexp"></td>
                    </tr>
                    <tr>
                        <td>CVV</td>
                        <td id="demoCvv"></td>
                    </tr>
                    <tr>
                        <td>Account Number</td>
                        <td id="demoCheckaccount"></td>
                    </tr>
                    <tr>
                        <td>Routing Number</td>
                        <td id="demoCheckaba"></td>
                    </tr>
                    <tr>
                        <td>Name on Account</td>
                        <td id="demoCheckname"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td class="googlePayButton"></td>
                    </tr>
                </table>
                <br>
                <button id="demoPayButton" type="button">Pay the money.</button>
            </form>
            <script>
                document.addEventListener('DOMContentLoaded', function () {
                    CollectJS.configure({
                        "paymentSelector" : "#demoPayButton",
                        "variant" : "inline",
                        "styleSniffer" : "false",
                        "googleFont": "Montserrat:400",
                        "customCss" : {
                            "color": "#0000ff",
                            "background-color": "#d0d0ff"
                        },
                        "invalidCss": {
                            "color": "white",
                            "background-color": "red"
                        },
                        "validCss": {
                            "color": "black",
                            "background-color": "#d0ffd0"
                        },
                        "placeholderCss": {
                            "color": "green",
                            "background-color": "#808080"
                        },
                        "focusCss": {
                            "color": "yellow",
                            "background-color": "#202020"
                        },
                        "fields": {
                            "ccnumber": {
                                "selector": "#demoCcnumber",
                                "title": "Card Number",
                                "placeholder": "0000 0000 0000 0000"
                            },
                            "ccexp": {
                                "selector": "#demoCcexp",
                                "title": "Card Expiration",
                                "placeholder": "00 / 00"
                            },
                            "cvv": {
                                "display": "show",
                                "selector": "#demoCvv",
                                "title": "CVV Code",
                                "placeholder": "***"
                            },
                            "checkaccount": {
                                "selector": "#demoCheckaccount",
                                "title": "Account Number",
                                "placeholder": "0000000000"
                            },
                            "checkaba": {
                                "selector": "#demoCheckaba",
                                "title": "Routing Number",
                                "placeholder": "000000000"
                            },
                            "checkname": {
                                "selector": "#demoCheckname",
                                "title": "Name on Checking Account",
                                "placeholder": "Customer McCustomerface"
                            },
                            "googlePay": {
                                "selector": ".googlePayButton",
                                "shippingAddressRequired": true,
                                "shippingAddressParameters": {
                                    "phoneNumberRequired": true,
                                    "allowedCountryCodes": ['US', 'CA']
                                },
                                "billingAddressRequired": true,
                                "billingAddressParameters": {
                                    "phoneNumberRequired": true,
                                    "format": "MIN"
                                },
                                'emailRequired': true
                            }
                        },
                        'price': '1.00',
                        'currency':'USD',
                        'country': 'US',
                        'validationCallback' : function(field, status, message) {
                            if (status) {
                                var message = field + " is now OK: " + message;
                            } else {
                                var message = field + " is now Invalid: " + message;
                            }
                            console.log(message);
                        },
                        "timeoutDuration" : 2000,
                        "timeoutCallback" : function () {
                            console.log("The tokenization didn't respond in the expected timeframe.  This could be due to an invalid or incomplete field or poor connectivity");
                        },
                        "fieldsAvailableCallback" : function () {
                            console.log("Collect.js loaded the fields onto the form");
                        },
                        'callback' : function(response) {
                            alert(response.token);
                            var input = document.createElement("input");
                            input.type = "hidden";
                            input.name = "payment_token";
                            input.value = response.token;
                            var form = document.getElementsByTagName("form")[0];
                            form.appendChild(input);
                            form.submit();
                        }
                    });
                });
            </script>
        </body>
    </html>

Expert Inline Example


    <html>
        <head>
            <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
            <script>
                document.addEventListener('DOMContentLoaded', function () {
                    CollectJS.configure({
                        'paymentSelector' : '#customPayButton',
                            "fields": {
                            "ccnumber": {
                                "selector": "#demoCcnumber",
                                "title": "Card Number",
                                "placeholder": "0000 0000 0000 0000"
                            },
                            "ccexp": {
                                "selector": "#demoCcexp",
                                "title": "Card Expiration",
                                "placeholder": "00 / 00"
                            },
                            "cvv": {
                                "display": "show",
                                "selector": "#demoCvv",
                                "title": "CVV Code",
                                "placeholder": "***"
                            },
                            "checkaccount": {
                                "selector": "#demoCheckaccount",
                                "title": "Account Number",
                                "placeholder": "0000000000"
                            },
                            "checkaba": {
                                "selector": "#demoCheckaba",
                                "title": "Routing Number",
                                "placeholder": "000000000"
                            },
                            "checkname": {
                                "selector": "#demoCheckname",
                                "title": "Name on Checking Account",
                                "placeholder": "Customer McCustomerface"
                            },
                            "googlePay": {
                                "selector": ".googlePayButton",
                                "shippingAddressRequired": true,
                                "shippingAddressParameters": {
                                    "phoneNumberRequired": true,
                                    "allowedCountryCodes": ['US', 'CA']
                                },
                                "billingAddressRequired": true,
                                "billingAddressParameters": {
                                    "phoneNumberRequired": true,
                                    "format": "MIN"
                                },
                                'emailRequired': true
                            }
                        },
                        "price": "1.00",
                        "currency":"USD",
                        "country": "US",
                        "variant": "inline",
                        "callback" : function(response) {
                            alert(response.token);
                            var input = document.createElement("input");
                            input.type = "hidden";
                            input.name = "payment_token";
                            input.value = response.token;
                            var form = document.getElementsByTagName("form")[0];
                            form.appendChild(input);
                            form.submit();
                        }
                    });
                });
            </script>
        </head>
        <body>
            <h1>CollectJS Payment Form</h1>
            <form action="/your-page.php" method="post">
                <table>
                    <tr>
                        <td>First Name</td>
                        <td><input size="30" type="text" name="fname" value="Test" /></td>
                    </tr>
                    <tr>
                        <td>Last Name</td>
                        <td><input size="30" type="text" name="lname" value="User" /></td>
                    </tr>
                    <tr>
                        <td>Address</td>
                        <td><input size="30" type="text" name="address" value="123 Main Street"></td>
                    </tr>
                    <tr>
                        <td>City</td>
                        <td><input size="30" type="text" name="city" value="Beverley Hills"></td>
                    </tr>
                    <tr>
                        <td>State</td>
                        <td><input size="30" type="text" name="state" value="CA"></td>
                    </tr>
                    <tr>
                        <td>Zip</td>
                        <td><input size="30" type="text" name="zip" value="90210"></td>
                    </tr>
                    <tr>
                        <td>Country</td>
                        <td><input size="30" type="text" name="country" value="US"></td>
                    </tr>
                    <tr>
                        <td>Phone</td>
                        <td><input size="30" type="text" name="phone" value="5555555555"></td>
                    </tr>
                    <tr>
                        <td>CC Number</td>
                        <td id="demoCcnumber"></td>
                    </tr>
                    <tr>
                        <td>CC Exp</td>
                        <td id="demoCcexp"></td>
                    </tr>
                    <tr>
                        <td>CVV</td>
                        <td id="demoCvv"></td>
                    </tr>
                    <tr>
                        <td>Account Number</td>
                        <td id="demoCheckaccount"></td>
                    </tr>
                    <tr>
                        <td>Routing Number</td>
                        <td id="demoCheckaba"></td>
                    </tr>
                    <tr>
                        <td>Name on Account</td>
                        <td id="demoCheckname"></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td class="googlePayButton"></td>
                    </tr>
    
                </table>
                <br>
                        This form will be automatically submitted after 30 seconds
                <script>
                    setTimeout("CollectJS.startPaymentRequest()", 30000);
                </script>
            </form>
        </body>
    </html>

Google Pay


Google Pay allows customers to provide credit card data saved in their Google accounts to be used in online payments. Collect.js supports Google Pay in both lightbox and inline integrations allowing you to capture these credit card details in either flow. And to make the integration as seamless as possible, the Google Pay data will be returned to you in the “payment_token” variable, so no matter what payment method your customers make, your transaction request can be exactly the same.

To use Google Pay, you must provide Collect.js country and currency values. These values are used to ensure the user can only select a valid card. You must also provide an HTML element on your page that Collect.js can use to draw the Google Pay button.

Google Pay is currently supported on TSYS – EMV and Elavon viaConex.

<html>
    <head>
        <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="000000-000000-000000-000000"
            data-variant="inline"
            data-country="US"
            data-price="1.00"
            data-currency="USD"
        ></script>
    </head>
    <body>
        <form action="submit_to_direct_post_api.php" method="post">
            <div id="googlepaybutton"></div>
        </form>
    </body>
    </html>

This will create a Google Pay button that will be inserted in the div as an iframe. The Google Pay button will be 240x70px, so make sure to leave room in this div for the button to display in full. When a user clicks the button, they are presented with a payment sheet requesting the user’s payment details. After the user submits the payment sheet, Collect.js executes the callback function if one were provided, or submits your form with the payment token attached.

Capture Billing and Shipping Data

Collect.js also allows you to capture the user’s shipping and billing details with Google Pay, just like the credit card data. This eliminates the need for you to capture this manually in your own web form. When these options are enabled, Google Pay will also request the user’s information and Collect.js will store all that data in the payment token.

In addition to the payment data that gets stored for all Google Pay transactions, the payment token will include the following shipping fields when shipping address required is enabled:

  • shipping_address_1
  • shipping_address_2
  • shipping_zip
  • shipping_city
  • shipping_state
  • shipping_country
  • shipping_firstname
  • shipping_lastname
  • phone (also requires phone_number_required to be enabled)

When billing_address_required is enabled, Collect.js will also capture these fields:

  • address1 (also requires format to be “FULL”)
  • address2 (also requires format to be “FULL”)
  • zip
  • city (also requires format to be “FULL”)
  • state (also requires format to be “FULL”)
  • country
  • firstname
  • lastname
  • phone (also requires phone_number_required to be enabled)
<html>
    <head>
        <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="000000-000000-000000-000000"
            data-variant="inline"
            data-field-google-pay-selector=".google-pay-button"
            data-field-google-pay-shipping-address-required="true"
            data-field-google-pay-shipping-address-parameters-phone-number-required="true"
            data-field-google-pay-shipping-address-parameters-allowed-country-codes="US,CA"
            data-field-google-pay-billing-address-required="true"
            data-field-google-pay-billing-address-parameters-phone-number-required="true"
            data-field-google-pay-billing-address-parameters-format="MIN"
        ></script>
    </head>
    <body>
        <form action="submit_to_direct_post_api.php" method="post">
            <div class="google-pay-button"></div>
        </form>
    </body>
    </html>

Simple Lightbox Implementation

See the Simple Example for a basic web page using this implementation.

The simplest way to integrate is by pasting in the following script tag to your web page (preferably in the header) where you’ll be collecting payments:


    <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here"></script>
 

With this script, you just need to add a button with the ID of “payButton” to your page inside a form where you ask for the customer’s information (name, address, email, etc.) You should make this button somewhere that indicates to the customer that they will be prompted to enter their card information and check out. Collect.js will find this button and display the below form in a lightbox over your website.


The customer will enter their card information and when they submit this mini-form, the lightbox will disappear, a hidden field will be inserted into your form with the “payment_token” value, and your form will be submitted.

You can then submit the transaction to the gateway with the Direct Post API using the “payment_token” variable.

Advanced Lightbox Implementation

See the advanced HTML example and >advanced JavaScript example files for examples.

If you want to have a little more control over the default behavior, you can pass in additional data elements in the script tag. Here’s an example using all the available variables:


    <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="your-token-key-here"
            data-payment-selector=".customPayButton"
            data-primary-color="#ff288d"
            data-theme="bootstrap"
            data-secondary-color="#ffe200"
            data-button-text="Submit the Payment"
            data-instruction-text="Enter Card Information"
            data-payment-type="cc"
            data-field-cvv-display="hide"
            data-price="1.00"
            data-currency="USD"
            data-country="US"
            data-field-google-pay-shipping-address-required="true"
            data-field-google-pay-shipping-address-parameters-phone-number-required="true"
            data-field-google-pay-shipping-address-parameters-allowed-country-codes="US,CA"
            data-field-google-pay-billing-address-required="true"
            data-field-google-pay-billing-address-parameters-phone-number-required="true"
            data-field-google-pay-billing-address-parameters-format="MIN"
            data-field-google-pay-email-required="true"
    ></script>

Configuration Variables
Variable Format Behavior
data-tokenization-key String Authenticates the request
data-payment-selector String Tells Collect.js what class or id value will trigger the lightbox
Default: “#payButton”
data-primary-color String The HEX value for the color of the submit button in the lightbox
Default: “#007BFF”
data-theme String (“bootstrap” or “material”) The version of the payment form customers will see. All available themes will use the primary and secondary colors provided.
Default: “bootstrap”
data-secondary-color String The HEX value for the color of the lightbox border
Default: “#282828”
data-button-text String The text that will display on the submit button in the lightbox
Default: “Submit Payment”
data-instruction-text String The text that will display above the payment fields. Custom text should be short so as not to overlap with other elements in the lightbox.
Default: “Please enter payment info”
data-payment-type String (“cc” or “ck”) Whether the lightbox shows credit card or check fields (“cc” for credit cards or “ck” for checks)
Default: “cc”
data-field-cvv-display String (“show”, “hide”, or “required”) Whether the CVV field is required (“required”), optional (“show”), or not displayed at all (“hide”). Also supported as “data-field-cvv ” for legacy users.
Default: “required”
data-field-google-pay-selector String A CSS selector for the Google Pay field.
Default: “#googlepaybutton”
data-field-google-pay-shipping-address-required String (“true” or “false”) Determines whether or not Google Pay should capture shipping address information. Shipping information captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-shipping-address-parameters-phone-number-required String (“true” or “false”) Determines whether or not Google Pay should capture a phone number from the user’s shipping phone number. Phone numbers captured this way become stored in the payment token.
Default: “false”
data-field-google-pay-shipping-address-parameters-allowed-country-codes String (comma delimited list of 2 character country codes) List of allowed countries. Credit cards from outside these countries will not be displayed as acceptable options within the Google Pay payment sheet. Omitting this value allows credit cards from any country.
Default: undefined
data-field-google-pay-billing-address-required String (“true” or “false”) Determines whether or not Google Pay should capture billing address information. Billing information captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-billing-address-parameters-phone-number-required String (“true” or “false”) Determines whether or not Google Pay should capture a phone number from the user’s billing phone number. Phone numbers captured this way become stored in the payment token.
Default: “false”
data-field-google-pay-billing-address-parameters-format String (“MIN” or “FULL”) Determines which billing address fields to capture from the user. “MIN” provides “zip”, “country”, “first_name” and “last_name”. “FULL” additionally provides “address1”, “address2”, “city”, “state”.
Default: “MIN”
data-field-google-pay-email-required String (“true” or “false”) Determines whether or not Google Pay should capture an email address. Email addresses captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-button-type String (“short” or “long”) “long” displays as “Buy with Google Pay”. “short” displays the button with just the Google Pay logo.
Default: “long”
data-price String The final cost that the user will be charged.
Default: undefined
data-country String The country where the transaction is processed.
Required if using Google Pay
data-currency String The currency the transaction will use to process the transaction.
Required if using Google Pay
Collect.js Functions
Function Name Parameters Description
configure Object Call this when you’d like to reconfigure Collect.js. Collect.js will try to run this automatically on page load, but you can run it manually to change the configuration at any time.

This method optionally accepts an object with all configuration variables you’re using for Collect.js.
startPaymentRequest Event Call this to bring up the lightbox with the secure payment form for the customer to fill out. If you are using the “payButton” ID or custom payment selector, this will automatically be called when the customer clicks that element on the page.

This method accepts an event object as an optional parameter and will call the provided callback function with a token response and the optional event.
closePaymentRequest Call this to dismiss the lightbox. This replicates the behavior of the user clicking the “close” button inside the lightbox. No card or checking information will be saved.

You may also choose to configure Collect.js directly in your JavaScript, in which case you can do all of the above, and also implement a callback function that will execute when the customer submits the lightbox form. The payment token value will be returned in a “response” variable that you can do whatever you’d like with.

    
    {
        card: {
            number: "411111******1111",
            bin: "411111",
            exp: "1028",
            hash: "abcdefghijklmnopqrstuv1234567890",
        },
        check: {
            name: null,
            account: null,
            hash: null,
            aba: null,
        },
        token: "3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8",
        initiatedBy: Event,
    }

This implementation method allows for additional changes to the look and feel to better match your website’s UI

Expert Lightbox Implementation

If you have a webpage where you would like the lightbox to trigger without an element getting clicked, then you can call the following function:

CollectJS.startPaymentRequest(event)

This function will trigger the lightbox to show up and request payment details. If you wish to change any options, this should be done before calling this function since changes after this point wont affect the lightbox.

This function optionally receives an event object. If an event is passed into the startPaymentRequest function, that same event will exist in the callback’s response variable under “response.initiatedBy”. This can be used to track what event started the payment request and the next steps.

    
    {
        card: {
            number: null,
            bin: null,
            exp: null,
            hash: null,
        },
        check: {
            name: "Jane Doe",
            account: "1******23",
            hash: "abcdefghijklmnopqrstuv1234567890",
            aba: "123123123",
        },
        token: "3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8",
        initiatedBy: Event,
    }
    

If you wish to close the payment request without waiting for the user to click the close button, you can call the function:

CollectJS.closePaymentRequest()

This function will remove the lightbox from the page. No other functions will trigger from this function being called, including the callback.

Note that this implementation also requires you to include the standard script tag on the page as well.

Simple Integration Implementation

See the Simple Inline Example for a basic web page using this implementation.

While the Inline integration model offers many customizable options, you can also get started quickly with a basic form. First, install the following JavaScript on your payment form page, preferably in the HEAD element:


    <script src="https://centavo.transactiongateway.com/token/Collect.js" data-tokenization-key="your-token-key-here" data-variant="inline"></script>

This script assumes that you’ve set up a payment form already. The form can be laid out however you’d like, but there should be block-level elements (div, for example) where the sensitive payment info will be collected. The following IDs are expected to be used in place of standard form inputs:

For Credit Card Payments

  • ccnumber (Credit card number)
  • ccexp (Credit card expiration date)
  • cvv (CVV)

For Electronic Check Payments

  • checkname (Checking account name)
  • checkaccount (Checking account number)
  • checkaba (Routing number)

This is a very basic form that has integrated Inline Collect.js.

    
    <form>
        <input type="text" id="first_name">
        <input type="text" id="last_name">
        <input type="text" id="address">
        <div id="ccnumber"></div>
        <div id="ccexp"></div>
        <div id="cvv"></div>
        <input type="submit" id="payButton">
    </form>
    

These elements will have iframes inserted into them, contents of which will be hosted by the gateway. They will be full width text fields and will use the style sniffer to match the rest of your page. The ID values let us know what field is collecting what information from the customer.

In addition to the empty fields, there must be a submit button in the form with an ID of “payButton.” When the customer clicks this to submit the form, Collect.js will collect the data from all inline iframes and submit the form with a new “payment_token” value which is an encrypted version of the payment data.

After this form is submitted to your site, you can submit the data to the gateway via the Direct Post API. For example:


    security_key: 3456h45k6b4k56h54kj6h34kj6445hj4
    type: sale
    amount: 4.00
    payment_token: 3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8
    first_name: Jane
    last_name: Doe
    address: 123 Main St.

Advanced Implementation Method

See the advanced HTML example and advanced JavaScript example files for examples.

If the simple implementation does not give you everything you need, then you can use the advanced implementation to customize the experience more to your liking. The options available are extensive, and you may use as many or as few as you want. Below is an example of using every variable possible.


    <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="your-token-key-here"
            data-variant="inline"
            data-payment-selector="#demoPayButton"
            data-style-sniffer="false"
            data-google-font="Montserrat:400"
            data-validation-callback = "(function (field, valid, message) {console.log(field + ': ' + valid + ' -- ' + message)})"
            data-custom-css='{
                "background-color": "#a0a0ff",
                "color": "#0000ff"
            }'
            data-invalid-css='{
                "background-color":"red",
                "color":"white"
            }'
            data-valid-css='{
                "background-color":"#d0ffd0",
                "color":"black"
            }'
            data-placeholder-css='{
                "background-color":"#808080",
                "color":"green"
            }'
            data-focus-css='{
                "background-color":"#202020",
                "color":"yellow"
            }'
            data-timeout-duration = "2000"
            data-timeout-callback = "(function() {console.log('Timeout reached')})"
            data-fields-available-callback = "(function() {console.log('Collect.js has added fields to the form')})"
            data-field-ccnumber-selector = '#demoCcnumber'
            data-field-ccnumber-title = 'Card Number'
            data-field-ccnumber-placeholder = '0000 0000 0000 0000'
            data-field-ccexp-selector = '#demoCcexp'
            data-field-ccexp-title = 'Expiration Date'
            data-field-ccexp-placeholder = '00 / 00'
            data-field-cvv-display = 'required'
            data-field-cvv-selector = '#demoCvv'
            data-field-cvv-title = 'CVV Code'
            data-field-cvv-placeholder = '***'
            data-field-checkaccount-selector = '#demoCheckaccount'
            data-field-checkaccount-title = 'Account Number'
            data-field-checkaccount-placeholder = '000000000000'
            data-field-checkaba-selector = '#demoCheckaba'
            data-field-checkaba-title = 'Routing Number'
            data-field-checkaba-placeholder = '000000000'
            data-field-checkname-selector = '#demoCheckname'
            data-field-checkname-title = 'Account Name'
            data-field-checkname-placeholder = 'Customer Name'
            data-price="1.00"
            data-currency="USD"
            data-country="US"
            data-field-google-pay-shipping-address-required="true"
            data-field-google-pay-shipping-address-parameters-phone-number-required="true"
            data-field-google-pay-shipping-address-parameters-allowed-country-codes="US,CA"
            data-field-google-pay-billing-address-required="true"
            data-field-google-pay-billing-address-parameters-phone-number-required="true"
            data-field-google-pay-billing-address-parameters-format="MIN"
            data-field-google-pay-email-required="true"
    ></script>

Configuration Variables
Variable Format Behavior
data-tokenization-key String Authenticates the request
data-variant String (“inline” or “lightbox”) Whether to use “inline” or “lightbox” integration (required for inline integration)
Default: “lightbox”
data-payment-selector String Tells Collect.js what class or id value will trigger the form submission
Default: “#payButton”
data-style-sniffer String (“true” or “false”) Whether Collect.js should try to calculate the style of form fields in your current form and use that as a baseline style for the Collect.js fields (“true” to calculate style, “false” to start with unstyled text fields)
Default: “true”
data-validation-callback String A JavaScript function which will be called each time a Collect.js field attempts to validate. It will recieve three paramaters: a string indicating which field was validated (ccnum or checkname, for example), a boolean for whether or not it validated successfully, and a string which may provide more detailed information about why the validation failed. For broadest compatibility, enclose the function in parentheses like in the example above
data-custom-css JSON String The CSS rules that will be applied to the fields by default. These override anything provided through the style-sniffer, if used. The rules should be packaged as a JSON-formatted object, containing a key-value pair for each property’s name and value. Please see below for a list of the supported CSS properties
data-invalid-css JSON String The CSS rules that will be added to a field when it fails to validate. These override anything provided through the style-sniffer and the custom-css paramater, if used. The rules should be packaged as a JSON-formatted object, containing a key-value pair for each property’s name and value. Please see below for a list of the supported CSS properties
data-placeholder-css JSON String The CSS rules that will be added to a field when it’s displaying a placeholder. The rules should be packaged as a JSON-formatted object, containing a key-value pair for each property’s name and value. Please see below for a list of the supported CSS properties
data-focus-css JSON String The CSS rules that will be added to a field when it has the keyboard focus. The rules should be packaged as a JSON-formatted object, containing a key-value pair for each property’s name and value. Please see below for a list of the supported CSS properties
data-valid-css JSON String The CSS rules that will be added to a field when it successfully validates and saves. These override anything provided through the style-sniffer and the custom-css paramater, if used. The rules should be packaged as a JSON-formatted object, containing a key-value pair for each property’s name and value. Please see below for a list of the supported CSS properties
data-google-font String Directs Collect.js to load font collections available through Google Fonts. This only makes the fonts available in the fields; you must still provide (either directly or through the style sniffer) styles that specify them. List the font name, followed by a colon and the specific weights or variants needed.
Example: “Open Sans:400,700i”
data-timeout-duration Integer When form submission is triggered, Collect.js will wait only this long (in milliseconds) for payment data validation and recording to complete. If, by this time, Collect.js is still missing confirmation on vital fields, the data-timeout-callback function will be invoked
Default: “0” which disables the timeout
data-timeout-callback String A JavaScript function which gets called if data- timeout-duration has passed since we tried to submit the form, but we still haven’t confirmed that enough fields are stored with the token to make a viable payment. This allows for the site to retry submission, or ask the customer to try submission again, if an invalid entry or intermittent connection caused the data storage to fail. For broadest compatibility, enclose the function in parentheses like in the example above
Default: an internal function that displays a “Please submit the form again.” alert
data-fields-available-callback String A JavaScript function which gets called once Collect.js has installed the fields onto your page. A typical use case is to wire up event handlers to the fields when they are enterred or left. For broadest compatibility, enclose the function in parentheses like in the example above
data-field-ccnumber-selector String (CSS Selector) A CSS selector for the Credit Card Number inline field
Default: “#ccnumber”
data-field-ccnumber-title String A title for the Credit Card Number inline field
data-field-ccnumber-placeholder String Placeholder text for the Credit Card Number inline field
data-field-ccexp-selector String (CSS Selector) A CSS selector for the Credit Card Expiration Date inline field
Default: “#ccexp”
data-field-ccexp-title String A title for the Credit Card Expiration Date inline field
data-field-ccexp-placeholder String Placeholder text for the Credit Card Expiration Date inline field
data-field-cvv-display String (“show”, “hide”, or “required”) Whether the CVV field is required (“required”), optional (“show”), or not displayed at all (“hide”). If the CVV field is required, a space for it must be provided on the form. Also supported as data-field-cvv for legacy users
Default: “required”
data-field-cvv-selector String (CSS Selector) A CSS selector for the CVV inline field
Default: “#cvv”
data-field-cvv-title String A title for the CVV inline field
data-field-cvv-placeholder String Placeholder text for the CVV inline field
data-field-checkaccount-selector String (CSS Selector) A CSS selector for Checking Account Number inline field
Default: “#checkaccount”
data-field-checkaccount-title String A title for the Checking Account Number inline field
data-field-checkaccount-placeholder String Placeholder text for the Checking Account Number inline field
data-field-checkaba-selector String (CSS Selector) A CSS selector for the Checking Routing Number inline field
Default: “#checkaba”
data-field-checkaba-title String A title for the Checking Routing Number inline field
data-field-checkaba-placeholder String Placeholder text for the Checking Routing Number inline field
data-field-checkname-selector String (CSS Selector) A CSS selector for the Checking Account Name inline field
Default: “#checkname”
data-field-checkname-title String A title for the Checking Account Name inline field
data-field-checkname-placeholder String Placeholder text for the Checking Account Name inline field
data-field-google-pay-selector String A CSS selector for the Google Pay field.
Default: “#googlepaybutton”
data-field-google-pay-shipping-address-required String (“true” or “false”) Determines whether or not Google Pay should capture shipping address information. Shipping information captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-shipping-address-parameters-phone-number-required String (“true” or “false”) Determines whether or not Google Pay should capture a phone number from the user’s shipping phone number. Phone numbers captured this way become stored in the payment token.
Default: “false”
data-field-google-pay-shipping-address-parameters-allowed-country-codes String (comma delimited list of 2 character country codes) List of allowed countries. Credit cards from outside these countries will not be displayed as acceptable options within the Google Pay payment sheet. Omitting this value allows credit cards from any country.
Default: undefined
data-field-google-pay-billing-address-required String (“true” or “false”) Determines whether or not Google Pay should capture billing address information. Billing information captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-billing-address-parameters-phone-number-required String (“true” or “false”) Determines whether or not Google Pay should capture a phone number from the user’s billing phone number. Phone numbers captured this way become stored in the payment token.
Default: “false”
data-field-google-pay-billing-address-parameters-format String (“MIN” or “FULL”) Determines which billing address fields to capture from the user. “MIN” provides “zip”, “country”, “first_name” and “last_name”. “FULL” additionally provides “address1”, “address2”, “city”, “state”.
Default: “MIN”
data-field-google-pay-email-required String (“true” or “false”) Determines whether or not Google Pay should capture an email address. Email addresses captured this way becomes stored in the payment token.
Default: “false”
data-field-google-pay-button-type String (“short” or “long”) “long” displays as “Buy with Google Pay”. “short” displays the button with just the Google Pay logo.
Default: “long”
data-price String The final cost that the user will be charged.
Default: undefined
data-country String The country where the transaction is processed.
Required if using Google Pay
data-currency String The currency the transaction will use to process the transaction.
Required if using Google Pay
Collect.js Functions
Function Name Parameters Description
configure Object Call this when you’d like to reconfigure Collect.js. Collect.js will try to run this automatically on page load, but you can run it manually to change the configuration at any time. This will draw or re-draw all iframes onto the page.

This method optionally accepts an object with all configuration variables you’re using for Collect.js.
startPaymentRequest Event Call this when you want to save the data in the iframes and get the token value in the callback.

This method accepts an event object as an optional parameter. It will call the provided callback function with a token response and the optional event.
clearInputs Call this when you want to clear whatever the user has entered into any input provided by Collect.js.
JavaScript Based Activation

You may also choose to configure Collect.js directly in your JavaScript, For this, you will typically only include the data-tokenization-key parameter in the script tag, and deploy the other options with a CollectJS.configure() call. See the Advanced Inline JavaScript Example for a demonstration with the main available options. The CollectJS.configure function also lets you specify a callback function that will execute when the customer submits the payment form and payment info has been successfully stored. The callback takes the place of the default “add the payment token and submit the form” behavior and gets passed a “response” variable with the Payment Token. It is your responsibility to ensure this is posted to your server.


    {
        card: {
            number: "411111******1111",
            bin: "411111",
            exp: "1028",
            hash: "abcdefghijklmnopqrstuv1234567890",
        },
        check: {
            name: null,
            account: null,
            hash: null,
            aba: null,
        },
        token: "3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8",
        initiatedBy: Event,
    }

Styling Limitations

For security and compatibility reasons, the styling system- whether provided via custom-css, invalid-css, valid-css, focus-css or calculated using the style-sniffer, only supports the following CSS properties:

  • background-color
  • border-bottom-color
  • border-bottom-left-radius
  • border-bottom-right-radius
  • border-bottom-style
  • border-bottom-width
  • border-left-color
  • border-left-style
  • border-left-width
  • border-right-color
  • border-right-style
  • border-right-width
  • border-top-color
  • border-top-left-radius
  • border-top-right-radius
  • border-top-style
  • border-top-width
  • border-width
  • border-style
  • border-radius
  • border-color
  • bottom
  • box-shadow
  • color
  • cursor
  • direction
  • font-family
  • font-kerning
  • font-size
  • font-stretch
  • font-style
  • font-variant-caps
  • font-variant-numeric
  • font-weight
  • height
  • letter-spacing
  • line-height
  • margin-top
  • margin-bottom
  • opacity
  • outline-color
  • outline-offset
  • outline-style
  • outline-width
  • padding
  • padding-bottom
  • padding-left
  • padding-right
  • padding-top
  • pointer-events
  • text-align
  • text-align-last
  • text-decoration
  • text-decoration-line
  • text-decoration-style
  • text-decoration-color
  • text-decoration-skip-ink
  • text-underline-position
  • text-indent
  • text-rendering
  • text-shadow
  • text-size-adjust
  • text-overflow
  • text-transform
  • transition
  • vertical-align
  • white-space
  • will-change
  • word-break
  • word-spacing
  • hyphens

Placeholder CSS can only use the following attributes

  • background-color
  • font-family
  • font-kerning
  • font-size
  • font-stretch
  • font-style
  • font-variant-caps
  • font-variant-numeric
  • font-weight
  • word-spacing
  • letter-spacing
  • line-height
  • text-decoration
  • text-indent
  • text-transform
  • transition
  • vertical-align
  • opacity
  • color

Any other CSS properties will be ignored.

Expert Inline Implementation

Understanding the lifecycle of a Collect.js-enabled form

Each field that Collect.js supplies communicates with your Gateway independently. These fields will check the payment information, and if valid, direct the Gateway to save it, as soon as the customer exits a field. This process triggers the validation callbacks you can use to monitor the user’s progress and control their interactions with your form.

When the submit button is pressed (or CollectJS.startPaymentRequest is manually called), Collect.js directs each field to validate and save one last time. Once it gets back a notice of successful validation and saving from enough fields to make a viable payment request, it proceeds to submit the form or call an alternative callback as configured.

Once the Payment Token is used in a Direct Post request, it’s automatically destroyed. This prevents its reuse for a later unauthorized charge, but means that if you have to collect the payment information again (for example, after a declined transaction), you’re going to have to start fresh and generate a new token.

Manually Triggering Payment Information Saving

You can take control of when the final validate-and-save process is triggered. Rather than binding it explicitly to a payment button, you can call the following JavaScript function when ready.

CollectJS.startPaymentRequest(event)

When triggered, this causes the same behavior as pressing a payment button does by default: all the fields are told to validate and save. Once we confirm all data is stored, the callback you configured is executed.

This function optionally receives an event object. If an event is passed into the startPaymentRequest function, that same event will exist in the callback’s response variable under “response.initiatedBy”. This can be used to track what event started the recording request and the next steps.

    
    {
        card: {
            number: null,
            bin: null,
            exp: null,
            hash: null,
        },
        check: {
            name: "Jane Doe",
            account: "1******23",
            hash: "abcdefghijklmnopqrstuv1234567890",
            aba: "123123123",
        },
        token: "3455zJms-7qA2K2-VdVrSu-Rv7WpvPuG7s8",
        initiatedBy: Event,
    }
    

Note that this implementation also requires you to include the standard script tag on the page as well.

The expert example shows how the process can be triggered in code.

Integration with form validation

While Collect.js doesn’t let you directly access the contents of the payment information fields, it does provide several ways to check if they contain valid content. There are two distinct ways you can access this information in your form validation code:

1. Supply a “validation-callback”
This will listen for all Collect.js validation changes. This function will get a notice about each field change, and you can keep a tally during the form’s life.


    <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="your-token-key-here"
            data-validation-callback="(
                function(fieldName, valid, message) {
                    if (valid) {
                            ... store the fact that fieldName is valid ...
                    } else {
                            ... remove fieldName from the valid list, maybe display message to the user ...
                    }
                }
            )">
                    

2. Check CSS classes.
When you start the validation process, you can see if the elements you loaded Collect.js fields into have either CollectJSValid or CollectJSInvalid elements within them. Note that blank fields, or some fields in the process or being edited or saved, will have neither set. You can decide how to handle these depending on when you’re performing the check, what field is blank or unsaved, and how that fits into your site’s flow.


    validCardNumber = document.querySelector("#ccnumber .CollectJSValid") !== null;
    validExpiration = document.querySelector("#ccexp .CollectJSValid") !== null;
    validCvv = document.querySelector("#cvv .CollectJSValid") !== null;
    invalidCvv = document.querySelector("#cvv .CollectJSInvalid") !== null;
    blankOrUnsavedCvv = !validCvv && !invalidCvv;

Blur and Focus Events

Some styling techniques will change the classes of related elements as a user enters and leaves a form field. Google’s Material Design Components for the Web is a typical example– the label moves above the text, and an underline that’s not part of the field changes color. Collect.js exposes focus and blur events that can be used to trigger these types of effects with Collect.js fields.

Here’s a tangible example. The data-fields-available-callback code adds a listener to each Collect.js field’s blur and focus events. This listener adds or removes the active class from the nearest label. When a user enters the field, the label next to it changes from gray to bold and blue, reverting once they leave the field.


    <script
            src="https://centavo.transactiongateway.com/token/Collect.js"
            data-tokenization-key="your-token-key-here"
            data-variant="inline"
            data-fields-available-callback='
                    (function() {
                        var frames = document.querySelectorAll(".input-field iframe.CollectJSInlineIframe")
                        for (var i = 0; i < frames.length; i++) {
                            frames[i].addEventListener("focus", function (event) {
                                var panel = event.target.parentNode.parentNode;
                                panel.querySelector("label").classList.add("active");
                            });
                            frames[i].addEventListener("blur", function (event) {
                                var panel = event.target.parentNode.parentNode;
                                if(event.detail && event.detail.empty) {
                                    panel.querySelector("label").classList.remove("active");
                                }
                            });
                        }
                    });'
    ></script>
    
    <style>
        label {
            color: gray;
        }
        label.active {
            color: blue;
            font-weight: bold;
        }
    </style>
    
    <div class="input-field">
        <label for="ccnumber">Card Number</label>
        <div id="ccnumber"></div>
    </div>
    <div class="input-field">
        <label for="ccexp">Expiration Date</label>
        <div id="ccexp"></div>
    </div>
    <div class="input-field">
        <label for="cvv">CVV</label>
        <div id="cvv"></div>
    </div>

When the blur event is fired, it will include a detail structure with one element: empty. This tells you if the field is blank, so you can style it differently, without disclosing its contents.

Inline Integration Tips and Tricks

The Inline Integration system is powerful and flexible, so we’ve compiled some hints to help you make the most of it.

Styling Tips

If you specify the Style Sniffer option, Collect.js will first create a temporary INPUT element in the form at the location you targeted, and measure the styles from that element to model the actual field after. That means you can target individual payment fields via the CSS on your site. For example, you can add a special green border to just the credit card number field as follows:


    <script
        src="https://centavo.transactiongateway.com/token/Collect.js"
        data-tokenization-key="your-token-key-here"
        data-style-sniffer="true"
        data-field-ccnumber-selector = '#myCcnumber'></script>
    
    <style>
        #myCcnumber input {
            border-color: green;
            border-width: 3px;
            border-style: solid;
        }
    </style>
    
    <div id="myCcnumber"></div>

Styles provided by the Style Sniffer will be overridden by ones provided in the custom-css paramater, which in turn are overridden by the ones in the invalid-css paramater

Collect.js lays out its fields on your form with a “width” property of 100%, and a “height” calculated to fit the field as rendered plus provided margins. If you’d like to control the width of the field, or add horizontal space around it, you can specify width and/or padding on the block-level element that the field resides in, allowing the field itself to fill it in horizontally.

When styling CollectJSValid and CollectJSInvalid classes in your stylesheet, remember these represent the outer edge of an iframe that contains the field. Some CSS rules may not be very visible, or could behave unexpectedly. Body and background colors are unlikely to be visible, but borders and drop shadows are good choices.

Payment fields have to be retrieved from the Gateway and styled, so you may briefly see a blank space in your page during the loading process. This effect can be mitigated by styling the Collect.js fields to have no border or background, and applying those style components to the div, td, or other block-level element that contains them instead.

Integration Tips

It’s generally good practice to only let your customer enter credit card or check information on your payment form. However, Collect.js will allow you to include both credit card and electronic check fields in your form, so you could have a token that has encrypted data for both payment types. If all required fields are present for both payment types, then submitting a transaction in the Direct Post API with this payment_token will process a credit card sale by default, discarding the check data. To use the electronic check data instead, pass the payment variable in your Direct Post request with the value check.

The data-google-font option takes a font string in the same format as you get from the Google Font selection tool. That rool provides a stylesheet link like


    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,700i|Roboto:300,400" rel="stylesheet">

The section you need is the portion after family= . and before the closing quotation mark


    data-google-font="Montserrat:400,700,700i|Roboto:300,400"

If you intend to set up custom handlers for the blur or focus events, we suggest preparing a fields-available-callback function to set them up. That will ensure the events are handled as soon as the Collect.js fields are loaded into the page.

Defining a custom callback is a great way to integrate Collect.js into an AJAX-based purchase process. When the callback is activated, you can retrieve the payment-token and submit it with the rest of the form. confident that the payment info it represents is at least complete and sensibly formatted.

Validation Tips

For a smoother user experience, disable form submission until you have confirmed that the payment fields are successfully stored, as well as any other pre-transaction checks you perform. Collect.js won’t let the submission process complete until the payment information is sufficient to run a transaction, which may be surprising if a user tries to submit an incomplete or invalid form.


    function testXmlQuery($security_key,$constraints)
    {
        // transactionFields has all of the fields we want to validate
        // in the transaction tag in the XML output
        $transactionFields = array(
            'transaction_id',
            'partial_payment_id',
            'partial_payment_balance',
            'platform_id',
            'transaction_type',
            'condition',
            'order_id',
            'authorization_code',
            'ponumber',
            'order_description',
    
            'first_name',
            'last_name',
            'address_1',
            'address_2',
            'company',
            'city',
            'state',
            'postal_code',
            'country',
            'email',
            'phone',
            'fax',
            'cell_phone',
            'customertaxid',
            'customerid',
            'website',
    
            'shipping_first_name',
            'shipping_last_name',
            'shipping_address_1',
            'shipping_address_2',
            'shipping_company',
            'shipping_city',
            'shipping_state',
            'shipping_postal_code',
            'shipping_country',
            'shipping_email',
            'shipping_carrier',
            'tracking_number',
            'shipping_date',
            'shipping',
            'shipping_phone',
    
            'cc_number',
            'cc_hash',
            'cc_exp',
            'cavv',
            'cavv_result',
            'xid',
            'eci',
            'avs_response',
            'csc_response',
            'cardholder_auth',
            'cc_start_date',
            'cc_issue_number',
            'check_account',
            'check_hash',
            'check_aba',
            'check_name',
            'account_holder_type',
            'account_type',
            'sec_code',
            'drivers_license_number',
            'drivers_license_state',
            'drivers_license_dob',
            'social_security_number',
    
            'processor_id',
            'tax',
            'currency',
            'surcharge',
            'tip',
    
            'card_balance',
            'card_available_balance',
            'entry_mode',
            'cc_bin',
            'cc_type'
        );
    
        // actionFields is used to validate the XML tags in the
        // action element
         $actionFields = array(
             'amount',
             'action_type',
             'date',
             'success',
             'ip_address',
             'source',
             'api_method',
             'username',
             'response_text',
             'batch_id',
             'processor_batch_id',
             'response_code',
             'processor_response_text',
             'processor_response_code',
             'device_license_number',
             'device_nickname'
            );
    
        $mycurl=curl_init();
        $postStr='security_key='.$security_key.$constraints;
        $url="https://centavo.transactiongateway.com/api/query.php?". $postStr;
        curl_setopt($mycurl, CURLOPT_URL, $url);
        curl_setopt($mycurl, CURLOPT_RETURNTRANSFER, 1);
        $responseXML=curl_exec($mycurl);
        curl_close($mycurl);
    
        $testXmlSimple= new SimpleXMLElement($responseXML);
    
        if (!isset($testXmlSimple->transaction)) {
                throw new Exception('No transactions returned');
        }
    
        $transNum = 1;
        foreach($testXmlSimple->transaction as $transaction) {
            foreach ($transactionFields as $xmlField) {
                if (!isset($transaction->{$xmlField}[0])){
                    throw new Exception('Error in transaction_id:'. $transaction->transaction_id[0] .' id  Transaction tag is missing  field ' . $xmlField);
                }
            }
            if (!isset ($transaction->action)) {
                throw new Exception('Error, Action tag is missing from transaction_id '. $transaction->transaction_id[0]);
            }
    
            $actionNum = 1;
            foreach ($transaction->action as $action){
                foreach ($actionFields as $xmlField){
                    if (!isset($action->{$xmlField}[0])){
                        throw new Exception('Error with transaction_id'.$transaction->transaction_id[0].'
                                            Action number '. $actionNum . ' Action tag is missing field ' . $xmlField);
                    }
                }
                $actionNum++;
            }
            $transNum++;
        }
    
        return;
    }
    
    try {
    
        $constraints = "&action_type=sale&start_date=20060913";
        $result = testXmlQuery('6457Thfj624V5r7WUwc5v6a68Zsd6YEm',$constraints);
        print "Success.\n";
    
    } catch (Exception $e) {
    
        echo $e->getMessage();
    
    }


    const https = require('https');
    const querystring = require('querystring');
    
    const security_key = '{security_key}';
    const hostName = 'centavo.transactiongateway.com';
    const path = '/api/query.php';
    const actionType = 'sale'; // Can be any valid Query API action.
    
    // Create the post data body to pass into request
    const postData = querystring.stringify({
        'security_key': security_key,
        'action_type': actionType,
    });
    
    const options = {
        hostname: hostName,
        path: path,
        method: 'POST',
        headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
        }
    };
    
    // Make request to Query API
    const req = https.request(options, (response) => {
        console.log(`STATUS: ${response.statusCode}`);
        console.log(`HEADERS: ${JSON.stringify(response.headers)}`);
    
        response.on('data', (chunk) => {
        console.log(`BODY: ${chunk}`);
        });
        response.on('end', () => {
        console.log('No more data in response.');
        });
    });
    
    req.on('error', (e) => {
        console.error(`Problem with request: ${e.message}`);
    });
    
    // Write post data to request body
    req.write(postData);
    req.end();

Methodology

Query

Overview

While our online reporting interface allows merchants to quickly and easily retrieve detailed information about past transactions, a need for additional flexibility may be required. For example, a merchant may have custom accounting software that requires up-to-date information about the settlement status of all credit card transactions every day.

This document describes how developers can query our reporting engine directly to retrieve transaction reports in a machine readable format. Once the data has been retrieved, it can then be parsed and imported into a variety of software applications.

Communication

The communication protocol used to send messages to the Payment Gateway is through the HTTP protocol over an SSL connection (HTTPS). The format you must use is name/value pairs delimited by ampersand.

URL: https://centavo.transactiongateway.com/api/query.php
Example Post Data: security_key=security_key&transaction_id=123456789

You should POST your request to the Query API. The name/value pairs that are accepted by the Payment Gateway can be found in the ‘Variables’ section of this API.

The Query API can be tested with live credentials or a dedicated test account only. Please contact your Merchant Service Provider for more information.

The Query API will respond in Universal Time Coordinated (UTC).


Variables

Query

POST URL
POST URL: https://centavo.transactiongateway.com/api/query.php
Variable Name Description(Allowed Values)[Format]
security_key* API Security Key assigned to a merchant account.
New keys can be generated from the merchant control panel in Settings > Security Keys
condition A combination of values listed below can be passed and should be separated by commas. For example, to retrieve all transactions pending settlement or complete, the following could be used:

Example: condition=pendingsettlement,complete
pending: ‘Auth Only’ transactions that are awaiting capture.
pendingsettlement: This transaction is awaiting settlement.
in_progress: This Three-Step Redirect API transaction has not yet been completed. The transaction condition will change to ‘abandoned’ if 24 hours pass with no further action.
abandoned: This Three-Step Redirect API transaction has not been completed, and has timed out.
failed: This transaction has failed.
canceled: This transaction has been voided.
complete: This transaction has settled.
unknown: An unknown error was encountered while processing this transaction.
transaction_type Retrieves only transactions with the specified transaction type. Use one of the following to specify payment type:
cc: A credit card transaction.
ck: A check transaction.
action_type Retrieves only transactions with the specified action types. A combination of the values can be used and should be separated by commas. For example, to retrieve all transactions with credit or refund actions, use the following:

Example: action_type=refund,credit
sale: Sale transactions.
refund: Refund transactions.
credit: Credit transactions.
auth: ‘Auth Only’ transactions.
capture: Captured transactions.
void: Voided transactions.
return: Electronic Check (ACH) transactions that have returned, as well as credit card chargebacks.
source Retrieves only transactions with a particular ‘transaction source’. A combination of the values can be used and should be separated by commas. For example, to retrieve all transactions with api or recurring actions, use the following:

Example: source=api,recurring
api: API transactions.
batch_upload: Batch Upload transactions.
mobile: Mobile (iProcess) transactions.
quickclick: QuickClick transactions.
quickbooks: QuickBooks SyncPay transactions.
recurring: Recurring transactions when using Recurring module.
swipe: SwIPe Software transactions.
virtual_terminal: Virtual Terminal transactions.
internal: Internal transactions. Typically indicates settlement
transaction_id Specify a transaction ID or a comma separated list of transaction IDs to retrieve information on. Alternatively, provide a Subscription ID to retrieve processed (approved and declined) transactions associated with it.
subscription_id Set a specific subscription record or comma separated list of records. Using this with a transaction search will return all transactions associated with this subscription. This will return this subscription’s payment/plan information when used with report_type=recurring.
invoice_id Set a specific Invoice ID. Should only be used when report_type=invoicing.
partial_payment_id Retrieves only transactions with the specified partial payment ID.
order_id Retrieves only transactions with the specified Order ID.
first_name Retrieves only transactions with the specified first name.
last_name Retrieves only transactions with the specified last name.
address1 Retrieves only transactions with the specified specified address.
city Retrieves only transactions with the specified city.
state Retrieves only transactions with the specified state.
zip Retrieves only transactions with the specified zip/postal code.
phone Retrieves only transactions with the specified phone number.
fax Retrieves only transactions with the specified fax number.
order_description Retrieves only transactions with the specified order description.
drivers_license_number Retrieves only transactions with the specified driver’s license number.
drivers_license_dob Retrieves only transactions with the specified driver’s license date of birth.
drivers_license_state Retrieves only transactions with the specified driver’s license state.
email Retrieves only transactions with the specified billing email address.
cc_number Retrieves only transactions with the specified credit card number. You can use either the full number or the last 4 digits of the credit card number.
merchant_defined_field_# Retrieves only transactions with the specified merchant defined field value.
Replace the ‘#’ with a field number (1-20) (Example: merchant_defined_field_12=value)
start_date Only transactions that have been modified on or after this date will be retrieved. Note that any actions performed on a transaction will cause the modified date to be updated.

Format: YYYYMMDDhhmmss
end_date Only transactions that have been modified on or before this date will be retrieved. Note that any actions performed on a transaction will cause the modified date to be updated.

Format: YYYYMMDDhhmmss
report_type Allows customer vault information or a html receipt to be returned. If you would like to query the Customer Vault to view what customer information is stored in the Customer Vault, you must set the customer_vault variable.
If you omit the customer_vault_id, the system will return all customers that are stored in the vault. If you include a customer_vault_id, it will return the customer record associated with that ID.
Example: report_type=customer_vault&customer_vault _id=123456789
receipt: Will return an html receipt for a specified transaction id.
customer_vault: Set the Query API to return Customer Vault data.
recurring: Set the Query API to return subscription data.
recurring_plans: Set the Query API to return plan data.
invoicing: Set the Query API to return invoicing data.
gateway_processors: Will return Processor details a user has permissions for. Specify a “user” by querying with that security key.
account_updater: Will return Customer Vault data that has been updated using the Account Updater service.
test_mode_status: Will return whether the account has test mode active or inactive.
mobile_device_license Retrieves only transactions processed using the specified mobile device.
The device IDs for this parameter are available in the License Manager.
Use ‘any_mobile’ to retrieve all mobile transactions.
A combination of the values can be used and should be separated by commas.
Can not be used with ‘mobile_device_nickname’.

Example 1: mobile_device_license=D91AC56A-4242-3131-2323-2AE4AA6DB6EB
Example 2: mobile_device_license=any_mobile
mobile_device_nickname Retrieves only transactions processed using mobile devices with the specified nickname.
The nicknames for this parameter are available in the License Manager.
Can not be used with ‘mobile_device_license’.

Example (URL encoded): mobile_device_nickname=Jim’s%20iPhone
customer_vault_id Set a specific Customer Vault record. Should only be used when report_type=customer_vault.
date_search Allows Customer Vault information to be returned based on the ‘created’ or ‘updated’ date. If you would like to query the Customer Vault to view when customer information was created or updated, you must set the report_type variable with the customer_vault value.

If you omit the report_type variable, the system will ignore the date_search variable.

Example:
report_type=customer_vault&date_search=created,updated
&start_date=20170101000000&end_date=20201231232359
created: Will return Customer Vault data created during a specified date range.
updated: Will return Customer Vault data updated during a specified date range.
result_limit Determines the maximum number of results that may return for the current query.
page_number Determines which “page” of results are returned. For example, “result_limit=100&page_number=0” will return the first 100 results. Using “page_number=1” will return the next 100 results. Default is “0”.
result_order Determines order of in which results are returned. Default value is “standard”.
standard: Returns the results from oldest to newest.
reverse: Returns the results from newest to oldest.
invoice_status
Specify a comma separated list of what invoice statuses will return when using an “invoicing” report type.

Example: invoice_status=open,closed,paid
open: Open Invoices
paid: Paid Invoices
closed: Closed Invoices
past_due: Past Due Invoices

Sample Response

Query


    <nm_response>
        <transaction>
            <transaction_id>2612675976</transaction_id>
            <partial_payment_id></partial_payment_id>
            <partial_payment_balance></partial_payment_balance>
            <platform_id></platform_id>
            <transaction_type>cc</transaction_type>
            <condition>complete</condition>
            <order_id>1234567890</order_id>
            <authorization_code>123456</authorization_code>
            <ponumber></ponumber>
            <order_description></order_description>
            <first_name>John</first_name>
            <last_name>Smith</last_name>
            <address_1>123 Main St</address_1>
            <address_2>Apt B</address_2>
            <company></company>
            <city>New York City</city>
            <state>NY</state>
            <postal_code>10001</postal_code>
            <country>US</country>
            <email>johnsmith@example.com</email>
            <phone>1234567890</phone>
            <fax></fax>
            <cell_phone></cell_phone>
            <customertaxid></customertaxid>
            <customerid></customerid>
            <website></website>
            <shipping_first_name></shipping_first_name>
            <shipping_last_name></shipping_last_name>
            <shipping_address_1></shipping_address_1>
            <shipping_address_2></shipping_address_2>
            <shipping_company></shipping_company>
            <shipping_city></shipping_city>
            <shipping_state></shipping_state>
            <shipping_postal_code></shipping_postal_code>
            <shipping_country></shipping_country>
            <shipping_email></shipping_email>
            <shipping_carrier></shipping_carrier>
            <tracking_number></tracking_number>
            <shipping_date></shipping_date>
            <shipping>1.00</shipping>
            <shipping_phone></shipping_phone>
            <cc_number>4xxxxxxxxxxx1111</cc_number>
            <cc_hash>f6c609e195d9d4c185dcc8ca662f0180</cc_hash>
            <cc_exp>1215</cc_exp>
            <cavv></cavv>
            <cavv_result></cavv_result>
            <xid></xid>
            <eci></eci>
            <directory_server_id></directory_server_id>
            <three_ds_version></three_ds_version>
            <avs_response>N</avs_response>
            <csc_response>M</csc_response>
            <cardholder_auth></cardholder_auth>
            <cc_start_date></cc_start_date>
            <cc_issue_number></cc_issue_number>
            <check_account></check_account>
            <check_hash></check_hash>
            <check_aba></check_aba>
            <check_name></check_name>
            <account_holder_type></account_holder_type>
            <account_type></account_type>
            <sec_code></sec_code>
            <drivers_license_number></drivers_license_number>
            <drivers_license_state></drivers_license_state>
            <drivers_license_dob></drivers_license_dob>
            <social_security_number></social_security_number>
            <processor_id>processora</processor_id>
            <tax>1.00</tax>
            <currency>USD</currency>
            <surcharge></surcharge>
            <cash_discount></cash_discount>
            <tip></tip>
            <card_balance></card_balance>
            <card_available_balance></card_available_balance>
            <entry_mode>Keyed</entry_mode>
            <cc_bin>411111</cc_bin>
            <cc_type>visa</cc_type>
            <signature_image>
                iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAA
                    Cxjwv8YQUAAAAJcEhZcwAAEnQA
                ABJ0Ad5mH3gAAACGSURBVDhPlZGBEoAgCEO1//9nG83mxMrr3dkBG0hVW2vFqLX26CYbPIc7yS
                    AVe8LBq5u4elyV4M0NXIoGXYqA
                w4QqMAwJCRu+Az7HSlvgHtexlFKwGrLjG/h/rESmhrhRnLCKwjiNeLYv5QsXOoNSig8IsNYaZ0
                    tXJoGU9hU1k18XlZLOQHTenf7I
                cf3BwAAAABJRU5ErkJggg==
            </signature_image>
            <product>
                <sku>RS-100</sku>
                <quantity>1.0000</quantity>
                <description>Red Shirt</description>
                <amount>10.0000</amount>
            </product>
            <action>
                <amount>11.00</amount>
                <action_type>sale</action_type>
                <date>20150312215205</date>
                <success>1</success>
                <ip_address>1.1.1.1</ip_address>
                <source>virtual_terminal</source>
                <api_method></api_method>
                <username>demo</username>
                <response_text>SUCCESS</response_text>
                <batch_id>0</batch_id>
                <processor_batch_id></processor_batch_id>
                <response_code>100</response_code>
                <processor_response_text>NO MATCH</processor_response_text>
                <processor_response_code>00</processor_response_code>
                <requested_amount>11.00</requested_amount>
                <device_license_number></device_license_number>
                <device_nickname></device_nickname>
            </action>
            <action>
                <amount>11.00</amount>
                <action_type>level3</action_type>
                <date>20150312215205</date>
                <success>1</success>
                <ip_address>1.1.1.1</ip_address>
                <source>virtual_terminal</source>
                <api_method></api_method>
                <username>demo</username>
                <response_text></response_text>
                <batch_id>0</batch_id>
                <processor_batch_id></processor_batch_id>
                <response_code>100</response_code>
                <processor_response_text></processor_response_text>
                <processor_response_code></processor_response_code>
                <device_license_number></device_license_number>
                <device_nickname></device_nickname>
            </action>
            <action>
                <amount>11.00</amount>
                <action_type>settle</action_type>
                <date>20150313171503</date>
                <success>1</success>
                <ip_address></ip_address>
                <source>internal</source>
                <api_method></api_method>
                <username></username>
                <response_text>ACCEPTED</response_text>
                <batch_id>76158269</batch_id>
                <processor_batch_id>782</processor_batch_id>
                <response_code>100</response_code>
                <processor_response_text></processor_response_text>
                <processor_response_code>0000000000021980</processor_response_code>
                <device_license_number></device_license_number>
                <device_nickname></device_nickname>
            </action>
        </transaction>
    </nm_response>


    {
        "event_id": "9b312dfd-3174-4748-9447-d63c8744305a",
        "event_type": "transaction.sale.success",
        "event_body": {
            "merchant": {
                "id": "1234",
                "name": "Test Account"
            },
            "features": {
                "is_test_mode": true
            },
            "transaction_id": "1234560000",
            "transaction_type": "cc",
            "condition": "pendingsettlement",
            "processor_id": "ccprocessora",
            "ponumber": "123456789",
            "order_description": "this is a description",
            "order_id": "12345678",
            "customerid": "",
            "customertaxid": "",
            "website": "https://example.com",
            "shipping": "",
            "currency": "USD",
            "tax": "0.08",
            "surcharge": "",
            "tip": "",
            "requested_amount": "54.04",
            "shipping_carrier": "",
            "tracking_number": "",
            "shipping_date": "",
            "partial_payment_id": "",
            "partial_payment_balance": "",
            "platform_id": "",
            "authorization_code": "123456",
            "social_security_number": "",
            "drivers_license_number": "",
            "drivers_license_state": "",
            "drivers_license_dob": "",
            "billing_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "123123",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "555-555-5555",
                "cell_phone": "",
                "fax": "444-555-6666"
            },
            "shipping_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "123123",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "",
                "fax": ""
            },
            "card": {
                "cc_number": "411111******1111",
                "cc_exp": "1022",
                "cavv": "",
                "cavv_result": "",
                "xid": "",
                "eci": "",
                "avs_response": "N",
                "csc_response": "",
                "cardholder_auth": "",
                "cc_start_date": "",
                "cc_issue_number": "",
                "card_balance": "",
                "card_available_balance": "",
                "entry_mode": "",
                "cc_bin": "",
                "cc_type": ""
            },
            "action": {
                "amount": "54.04",
                "action_type": "sale",
                "date": "20200406175755",
                "success": "1",
                "ip_address": "1.2.3.4",
                "source": "virtual_terminal",
                "api_method": "virtual_terminal",
                "username": "exampleuser",
                "response_text": "SUCCESS",
                "response_code": "100",
                "processor_response_text": "",
                "processor_response_code": "",
                "device_license_number": "",
                "device_nickname": ""
            }
        }
    }


    {
        "event_id": "c1ee29d9-dd29-45d0-903a-c78da43bca32",
        "event_type": "transaction.sale.success",
        "event_body": {
            "merchant": {
                "id": "12345",
                "name": "Test Account"
            },
            "features": {
                "is_test_mode": true
            },
            "transaction_id": "1234560000",
            "transaction_type": "ck",
            "condition": "pendingsettlement",
            "processor_id": "ckprocessora",
            "ponumber": "",
            "order_description": "",
            "order_id": "",
            "customerid": "",
            "customertaxid": "",
            "website": "",
            "shipping": "",
            "currency": "USD",
            "tax": "1.00",
            "surcharge": "",
            "tip": "",
            "requested_amount": "60.49",
            "shipping_carrier": "",
            "tracking_number": "",
            "shipping_date": "",
            "partial_payment_id": "",
            "partial_payment_balance": "",
            "platform_id": "",
            "authorization_code": "123456",
            "social_security_number": "",
            "drivers_license_number": "",
            "drivers_license_state": "",
            "drivers_license_dob": "****-**-**",
            "billing_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "5555555555",
                "cell_phone": "",
                "fax": ""
            },
            "shipping_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "",
                "fax": ""
            },
            "check": {
                "check_account": "*****1234",
                "check_aba": "100000000",
                "check_name": "Jessica Jones",
                "account_holder_type": "personal",
                "account_type": "checking",
                "sec_code": "WEB"
            },
            "action": {
                "amount": "60.49",
                "action_type": "sale",
                "date": "20200406180124",
                "success": "1",
                "ip_address": "1.2.3.4",
                "source": "virtual_terminal",
                "api_method": "virtual_terminal",
                "username": "exampleuser",
                "response_text": "SUCCESS",
                "response_code": "100",
                "processor_response_text": "",
                "processor_response_code": "",
                "device_license_number": "",
                "device_nickname": ""
            }
        }
    }


    {
        "event_id": "e88bfc27-2d42-46a1-8427-65b4a7f11f16",
        "event_type": "transaction.sale.success",
        "event_body": {
            "merchant": {
                "id": "123456",
                "name": "Test Account"
            },
            "features": {
                "is_test_mode": true
            },
            "transaction_id": "1234560000",
            "transaction_type": "cs",
            "condition": "complete",
            "processor_id": "csprocessora",
            "ponumber": "",
            "order_description": "",
            "order_id": "",
            "customerid": "",
            "customertaxid": "",
            "website": "",
            "shipping": "",
            "currency": "USD",
            "tax": "1.00",
            "surcharge": "",
            "tip": "",
            "requested_amount": "60.49",
            "shipping_carrier": "",
            "tracking_number": "",
            "shipping_date": "",
            "partial_payment_id": "",
            "partial_payment_balance": "",
            "platform_id": "1",
            "authorization_code": "",
            "social_security_number": "",
            "drivers_license_number": "",
            "drivers_license_state": "",
            "drivers_license_dob": "",
            "billing_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "+15555555555",
                "cell_phone": "",
                "fax": ""
            },
            "shipping_address": {
                "first_name": "Jessica",
                "last_name": "Jones",
                "address_1": "123 Fake St.",
                "address_2": "",
                "company": "Alias Investigations",
                "city": "New York City",
                "state": "NY",
                "postal_code": "12345",
                "country": "US",
                "email": "someone@example.com",
                "phone": "",
                "fax": ""
            },
            "action": {
                "amount": "60.49",
                "action_type": "sale",
                "date": "20200406180150",
                "success": "1",
                "ip_address": "1.2.3.4",
                "source": "virtual_terminal",
                "api_method": "virtual_terminal",
                "username": "exampleuser",
                "response_text": "APPROVED",
                "response_code": "100",
                "processor_response_text": "Approved",
                "processor_response_code": "1",
                "device_license_number": "",
                "device_nickname": ""
            }
        }
    }


    {
        "event_id": "11750910-bd03-4f9a-871a-786203df177f",
        "event_type": "settlement.batch.complete",
        "event_body": {
            "batch_id": "12345678",
            "count": 4,
            "amount": "402.81",
            "merchant": {
                "id": "123456",
                "name": "Test Account"
            },
            "processor": {
                "id": "ccprocessor",
                "name": "CC Processor",
                "type": "cc"
            },
            "by_card_type": {
                "visa": {
                    "count": 4,
                    "amount": "402.81"
                }
            },
            "transaction_ids": [
                "1234000000",
                "1234000001",
                "1234000002",
                "1234000003"
            ]
        }
    }


    {
        "event_id": "dfe8156d-5dd9-43ac-8928-3cf70ef74108",
        "event_type": "settlement.batch.failure",
        "event_body": {
            "batch_id": "123456",
            "merchant": {
                "id": "123456",
                "name": "Test Merchant"
            },
            "processor": {
                "id": "ccprocessor",
                "name": "CC Processor",
                "type": "cc"
            }
        }
    }


    {
        "event_id": "d5b08691-cf24-41a4-9a5f-af8a1f5e2a13",
        "event_type": "chargeback.batch.complete",
        "event_body": {
            "merchant": {
                "id": "123456",
                "name": "Test Account"
            },
            "processor": {
                "id": "ccprocessor",
                "name": "CC Processor",
                "type": "cc"
            },
            "count": 2,
            "chargeback_amount": "11.11",
            "chargebacks": [
                {
                    "id": "1234567890",
                    "date": "3/29/2020",
                    "customer_name": "Someone Smith",
                    "cc_number": "411111******1111",
                    "amount": "11.11",
                    "reason": "101: Introductory chargeback"
                },
                {
                    "id": "1234567891",
                    "date": "3/29/2020",
                    "customer_name": "Another Person Jr.",
                    "cc_number": "543111******1111",
                    "amount": "18.11",
                    "reason": "101: Introductory chargeback"
                }
            ]
        }
    }

Setting Up Webhooks

Before anything else, you need to have a URL endpoint set up to receive POST requests. This will be a server location that you control and can use to process webhook messages as they are delivered.

Step 1

From the Settings > Webhooks page, click the “Add Endpoint” button.

Step 2

Enter your webhook receiver URL and select all event types you would like to be notified of from the list. As soon as the URL is saved, you will start to receive events at the URL specified; there is no further setup required. Please note that all URLs must start with “https” and have valid TLS encryption enabled.

Step 3

The Webhooks settings page shows your webhooks signing key. This value should be used on your website to authenticate that it is the gateway delivering these messages and not a third party.
Here is an example implementation in PHP:


    function webhookIsVerified($webhookBody, $signingKey, $nonce, $sig) {
        return $sig === hash_hmac("sha256", $nonce . "." . $webhookBody, $signingKey);
    }
    
    try {
        $signingKey = "YOUR_SIGNING_KEY_HERE";
        $webhookBody = file_get_contents("php://input");
        $headers = getallheaders();
        $sigHeader = $headers['Webhook-Signature'];
    
        if (!is_null($sigHeader) && strlen($sigHeader) < 1) {
        throw new Exception("invalid webhook - signature header missing");
    }
    
        if (preg_match('/t=(.*),s=(.*)/', $sigHeader, $matches)) {
        $nonce = $matches[1];
        $signature = $matches[2];
    } else {
        throw new Exception("unrecognized webhook signature format");
    }
    
        if (!webhookIsVerified($webhookBody, $signingKey, $nonce, $signature)) {
        throw new Exception("invalid webhook - invalid signature, cannot verify sender");
    }
    
        // webhook is now verified to have been sent by us, continue processing
    
        echo "webhook is verified";
        $webhook = json_decode($webhookBody);
        var_export($webhook);
    } catch (Exception $e) {
        echo "error: $e\n";
    }

Step 4

Webhooks will only be delivered from the following IP addresses. It is advisable to limit your webhook endpoints to only receive requests originating from these addresses:
104.192.32.81 through 104.192.32.87
104.192.36.81 through 104.192.36.87

Retry Logic

If we try to deliver a webhook notification to your endpoint and do not get an HTTP 200 response, the gateway will reattempt delivery up to 20 times. Over the course of 3 days we will keep trying until a success response is received. If no success response is received in this time period the notification will stop attempting and will not be delivered.

The retry logic is not essential for your software to know, but the approximate interval between delivery retires are:

  • 1 attempt 15 seconds after the initial attempt
  • 3 attempts every 60 seconds
  • 1 attempt 5 minutes later
  • 1 attempt 15 minutes later
  • 1 attempt 30 minutes later
  • 10 attempts every hour
  • 2 attempts every 12 hours
  • 1 final attempt after 24 more hours

Events

Each endpoint can be subscribed to specific events that happen in the gateway. Most events have multiple versions: success, failure, and unknown.

Available Event Types
Event Category Description
Transactions Sales, auths, captures, voids, refunds, and credits. Each transaction type can be filtered by successful, failed, and unknown transactions.
Settlement Batch summaries and can be filtered by successful and failed settlements.
Chargebacks If your processor supports chargeback reporting, chargebacks can be delivered as events.

Gateway Emulator

Third Party Shopping Carts

We have designed our gateway to be able to handle transaction submissions and responses in the Authorize.Net format. We call this our Gateway Emulator.

To use the Gateway Emulator, your shopping cart or application must support the Authorize.Net AIM or SIM method of integration. If the application supports the AIM or SIM method, you simply need to change the transaction POST URL to our Gateway Emulator URL.

The Gateway does not support the emulation of XML AIM, CIM, ARB, DPM, Card Present or Transaction Details APIs.

Our Gateway Emulator URL is:

AIM: https://centavo.transactiongateway.com/gateway/transact.dll
SIM: https://centavo.transactiongateway.com/cart/ausi.php

You will need to change any production and test Authorize.Net URLs to one of the above URLs. The following URLs should be replaced:

https://secure.authorize.net/gateway/transact.dll
https://test.authorize.net/gateway/transact.dll

Some applications will not contain the test URL. In that case, you will only be changing one URL. Once you have updated the URLs to point to us, the application will submit transactions without needing changes to the code base.

You will then need to configure the Authorize.Net AIM or SIM payment module with the following credentials:

  • API ID or Login ID is your gateway username.
  • Transaction Key is your gateway password.
  • The MD5 Hash is the word “gateway” without the marks.

For testing, you can use the username and password of “demo” and “password”.

CIT/MIT is supported even though the official AIM API does not support it. Please use the variable names and values documented under the Direct Post API on all relevant transactions.

Authorize.Net Modern XML Emulator

If your application is using Authorize.Net’s current XML API, then you can connect using our newest emulator. Like the above-mentioned emulators, this will accept requests in the same XML format that Auth.Net would accept, so it’s just a matter of changing your POST URL to the one below and using your gateway credentials for authentication. This emulator also emulates the response so that should look the same to your software.

Our Modern XML Emulator URL is:

https://centavo.transactiongateway.com/api/transrequest.php

For authentication, this API looks for “name” and “transactionKey”.

  • “name” can be anything, as it is not used for authentication.
  • “transactionKey” is your API Security Key.
Sparrow

If your application is using SparrowOne’s Services API, you can connect your software to the gateway via this emulator. Simply replace the POST URL in your software to the following address and you can submit transactions, add update, and delete Customer Vault IDs, and create recurring subscriptions.

https://centavo.transactiongateway.com/api/spar.php

Authentication uses your merchant account’s API Security Key in the ‘mkey’ variable.

Supported Devices

IPS Enterprise and IPS Encrypted Card Readers
The IPS devices are audio jack-connected card readers. Unlike the IDTECH Shuttle, these readers are powered by an internal battery. The IPS devices have a fast startup time and do not produce a constant tone through the audio jack.

Because the IPS devices connect through the audio port and there is no way to immediately detect the device type, you will receive a deviceConnected: event even if the user has only plugged in headphones. Since there is no activation with the IPS devices, a deviceActivated: and deviceBecameReadyForSwipe: will also be sent immediately. In order to be sure that the device is an IPS Enterprise or IPS, the PGSwipeIpsEnterprise and PGSwipeIps provide a beginTestCommunication: method you can use to attempt to communicate with the devices. Success is returned when the device has been successfully identified. This is not done by default to eliminate a delay before the device becomes active.

Both Android and iOS SDKs support the iPS Enterprise Encrypted Card Reader and the UniMag Card Reader. The legacy iPS Encrypted Reader is only supported on Android.

iDynamo
The iDynamo connects to the mobile device via Apple’s dock connector and is only compatible with iOS devices that use the older 30-pin (non-Lightning) dock connector.

When physically attached, the iDynamo is almost immediately ready to receive swipe events. When connected, the Swipe Delegate should expect a deviceConnected: message, immediately followed by a deviceActivationFinished: message, then a deviceBecameReadyForSwipe: message.

When the device is physically detached, the delegate receives the events in reverse order, i.e. deviceBecameUnreadyForSwipe:, deviceDeactivated:, deviceDisconnected:.

App Store: To support the iDynamo on an app distributed through the App Store, Apple may require you to contact MagTek for information before they will process your submission. To disable iDynamo support, do not add it to “Supported external accessory protocols” in your info.plist. You will still receive connect and disconnect events, but activation will fail, so be sure to check if the sending device is the iDynamo object and ignore it if so.

Known Issue with the iDynamo: There is an issue with device disconnection with the iDynamo and iOS’s ExternalAccessory framework. Upon disconnection, the stream communicating with the device is closed, during which you may receive the warning: [NSCondition dealloc]: condition ( ‘(null)’) deallocated while still in use. After reconnecting, a later disconnect may randomly cause the app to crash with an attempt to send a message to the deallocated instance. This does not occur frequently, and is more likely to occur when rapidly opening and closing the application (which sends a disconnect followed by a reconnect when the app re-opens). This issue is with Apple’s accessory-handling framework. Apple is aware of the issue and may fix it in a future iOS release.

IDTECH Shuttle The Shuttle (referred to in code as a UniMag device) is an audio jack-connected card reader. It is powered by a tone from the iPod / iPad / mobile phone. Before the Shuttle can receive swipes, it must be powered up.

Because the Shuttle connects through the audio port and there is no way to detect the device type until the device is activated, you will receive deviceConnected events whenever any device is attached to that port. For example, if the user attaches headphones, you will receive a connection event from the Mobile SDK.

The Mobile SDK can be configured to automatically attempt to power on the swipe reader immediately (this is the default), or you can disable the automatic activation and only activate the device when desired (e.g. on a payment screen, or when the user clicks a button).

Important: When powering on the device, the audio volume must be at maximum (done automatically by default). The tone generated through the audio port to activate the device can be very painful to a listener if they have connected speakers or headphones. For this reason, swipeController.uniMagReader.messageOptions.activateReaderWithoutPromptingUser is set to NO by default, causing the SDK to prompt the user for confirmation before activating the reader.

The Shuttle saves battery by only allowing swipes when a swipe has been requested, and a timeout occurs if a swipe is not received quickly enough (20 seconds by default). For simplicity, the SDK defaults to automatically requesting a swipe on activation and continuously renewing the swipe request. If you have issues with battery life, you can set swipeController.uniMagReader.alwaysAcceptSwipe to NO and manually call [swipeController.uniMagReader requestSwipe] when ready for a swipe.

Methodology

Mobile SDK

Overview

There are two parts to the Mobile SDK, the end-to-end encryption method and the swipe device library.

End-to-End Encryption

The end-to-end encryption library allows credit card data to be encrypted on a mobile device before sending it to the Merchant’s back-end server. During the sale process, the Merchant’s server can send the encrypted card data to the Payment Gateway, where it is decrypted and treated like a normal credit card. This gives the merchant more control of mobile transactions without having to increase compliance costs.

The merchant’s encryption key is an RSA public key that is unique to them. This means that the encrypted credit card data will only be able to be used to make a transaction in that merchant’s payment gateway account. Only the Payment Gateway has access to the private key that corresponds to this public key.

Card data is encrypted using AES encryption with a new randomly generated key for every card. This key is then encrypted with the public key along with the card data. This packet (the encrypted card and AES key) is unreadable to anybody without the private key which is only known to the Payment Gateway.

Note: The public key cannot be used to decrypt an encrypted card. Once encrypted, the card is unusable except by the Gateway when it processes the payment for the merchant. For this reason, there is no need to keep the public key a secret.

Swipe Device Library

This library supports the encrypted card readers supported by the payment gateway. This includes parsing the data and notifying you when a card reader is connected, disconnected, ready to receive a swipe, etc.

Using the Library

Mobile SDK: Android

Creating a Project

The fastest way to get started is to check out the Client Encryption Example project that can be downloaded from the downloads section. Or if you prefer to create your own project, use these steps:

    These directions are specific to Android Studio.
  1. Download and extract the zip file from the integration section of the Payment Gateway.
  2. In Android Studio’s Quick Start menu, select ‘Start a new Android Studio project’.
  3. Add SDK to project
    1. In the Project view(Alt + F1), select Project in the drop down menu instead of Android on top of the side-bar.
    2. Copy and paste the SDK into the libs folder underneath app.
  4. Modify gradle build file.
    1. Open build.gradle file located in the app directory.
    2. Add the following code snippet:
      
          repositories {
              flatDir {
                  dirs 'libs'
              }
          }
      
      
    3. In the dependencies section, add this code(replace {applicationId} with the applicationId in your default config):
      
          compile '{applicationId}:payment:gateway@aar'
      
      
Network Usage Note

You may notice the library attempting to connect to IDTECH’s website to download a file. Since the audio jack capabilities of different Android devices vary, the IDTECH Shuttle’s library uses different communication settings for each supported device. IDTECH frequently updates a list of the supported devices and the communication settings for each which the library may attempt to download from IDTECH. Internet permission is required.

End-to-End Encryption

Mobile SDK: Android

Acquiring a Public Key
  1. After logging into the Payment Gateway, navigate to Settings -> Security Keys -> View Mobile SDK Key. You can click on the Java example button to get a version that can easily be copied and pasted into your project.

  2. Use the Query API. In order to get the public key, you will need to use ‘report_type=sdk_key’. The key will be returned in the <sdk_key> tag.

Encrypting a Card

The following is an example of the entire encryption process:


    import com.SafeWebServices.PaymentGateway.PGEncrypt;

    PGEncrypt pg = new PGEncrypt();
    Pg. setKey(
        "***999|MIIEEjCCA3ugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBvTELMAkGA1UEBh"
        "MCVVMxETAPBgNVBAgTCElsbGlub2lzMRMwEQYDVQQHEwpTY2hhdW1idXJnMRgwFg"
                        [Several lines omitted]
        "cNAQEEBQADgYEAKY8xYc91ESNeXZYTVxEsFA9twZDpRjSKShDCcbutgPlC0XcHUt"
        "a2MfFPsdgQoq0I8y1nEn1qJiOuEG1t9Uwux4GAvAPzsWSsKyKQkZhqxrxkJUB39K"
        "Pg57pPytfJnlQTgYiSrycCEVHdDvhk92X7K2cab3aVV1+j0rKlR/Sy6b4=***");
    
    
    PGKeyedCard cardData = new PGKeyedCard(cardNumber, expiration, cvv);
    Boolean includeCVV = true;
    String encryptedCardData = pg.encrypt(cardData, includeCVV);

In this example, ‘encryptedCardData’ would now contain a string that can be passed to the Payment Gateway in place of credit card information. The parameter name to use when passing this value is ‘encrypted_payment’.

For example, a simple DirectPost API string would look something like this:

(This example assumes your Merchant server is running a PHP script that has received the encrypted card data through a POST parameter called ‘cardData’.)


    //Business logic, validation, etc.  When ready to process the payment...
    $cardData = $_POST['cardData'];
    $postString = "security_key=6457Thfj624V5r7WUwc5v6a68Zsd6YEm&type=sale&amount=1.00
                        &encrypted_payment=$cardData";
    
    //Post to Gateway

We suggest using POST instead of GET to reduce the possibility of the data being kept in a log file. For more information on how to communicate with the Payment Gateway, see the API documentation.

Swipe Devices

Mobile SDK: Android

Permissions

You will need to grant the application multiple permissions in order to use a swipe device. This can be done by modifying the manifest file by adding:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

In the class that intends to handle swipe events, add a PGSwipeController property called swipeController, and then in your init function, initialize the object with this line:


    //This example is for the iPS Encrypted Mobile Card Reader
    swipeController = new PGSwipeController(this, PGSwipeDevice.SwipeDevice.IPS);

If you want to change the default settings, you can change them now. Here are some examples:

swipeController.getDevice().setSwipeTimeout(30);
    swipeController.getDevice().setAlwaysAcceptSwipe(false);
    swipeController.getDevice().setActivateReaderOnConnect(false);

Your class will have to implement the PGSwipeListener protocol. If you are only interested in knowing when a card is swiped, you can safely leave every other event handler empty, as shown here (or add your own code to, for example, display an image indicating that the swipe reader is ready for a swipe). In this example, when the swipe is received, the card data is saved in a property (swipedCard) for eventual transmission to the Gateway (not shown), and two TextView variables (cardNumberField and expirationField) are set to show the masked card number and expiration date. If a bad swipe occurs, onSwipedCard is still called, but “card” will be null.

@Override
    public void onDeviceConnected(final PGSwipeDevice device)
    {
    }
    @Override
    Public void onDeviceDisconnected(final PGSwipeDevice device)
    {
    }
    
    @Override
    public void onDeviceActivationFinished(final PGSwipeDevice device)
    {
    }
    @Override
    public void onDeviceDeactivated(final PGSwipeDevice device)
    {
    }
    @Override
    public void onDeviceReadyForSwipe(final PGSwipeDevice device)
    {
    }
    @Override
    public void onDeviceUnreadyForSwipe(final PGSwipeDevice device,
        PGSwipeDevice.ReasonUnreadyForSwipe reason)
    {
    }
    @Override
    public void onSwipedCard(final PGSwipedCard card, final PGSwipeDevice device)
    {
        if (card != null) {
            this.runOnUiThread(new Runnable() {
            public void run() {
                TextView cardNumberField = (TextView)findViewById(R.id.cardNumber);
            cardNumberField.setText((CharSequence)card.getMaskedCardNumber());
            }
            }
        } else {
            //A null card means that there was a swipe but it was unsuccessful.    }
    }

Classes Overview

Mobile SDK: Android

PGEncrypt

The PGEncrypt class contains all necessary to encrypt data to be sent to the payment gateway. Merchants wanting to send transaction data to their servers before processing the transaction will want to use this method in order to prevent their server from touching sensitive data.

  • void setKey(String key)

    This method takes in the public key and sets it to be used with the encrypt method.

  • String encrypt(String plaintext)

    This method accepts a string to be encrypted. Although any string can be passed, the Payment Gateway will only pull fields related to credit cards from the encrypted text.

  • String encrypt(PGCard card, boolean includeCVV)

    This is the preferred way of getting the encrypted card data. It will format and encrypt the card data for you to pass on to the gateway.

PGSwipeDevice

This class represents the functionality that is common to the swipe reader devices. A PGSwipeDevice object is passed along with every even generated by the devices in order to identify the device type and access device-specific features by casting it to the specific swipe device.

  • enum ReasonUnreadyForSwipe {DISCONNECTED, TIMED_OUT, CANCELED, REFRESHING, SWIPE_DONE }

    Used to explain why the device can no longer accept a swipe.

  • enum SwipeDevice { UNIMAG, IPS, ENTERPRISE }

    Used to identify the type of device being used.

  • boolean getIsConneced()

    Returns true if the swipe device is connected.

  • boolean getIsActivated()

    Returns true if the swipe device is activated.

  • boolean getIsReadyForSwipe()

    Returns true if the swipe device is ready.

  • SwipeDevice getDeviceType()

    Returns the current device type.

  • void setListener(SwipeListener value)

    Sets the event listener.

  • boolean setSwipeTimeout(int seconds)

    Sets the timeout interval for the swipe device.

  • void setAlwaysAcceptSwipe(boolean alwaysAcceptSwipe)

    True by default, if this is set to false, a swipe must be requested once the device is ready.

  • void setActivateReaderOnConnect(boolean activateReaderOnConnect)

    True by default, if this is to false, the device must be activated before it can be used.

  • boolean requestSwipe()

    Notifies the reader to start waiting for a swipe. The device must be active before this can be called.

  • void cancelSwipeRequest()

    Cancels a swipe request.

  • void stopSwipeController()

    Cancels the current swipe request, unregisters the swipe device, and frees resources. Will not receive any information from the device until it is resumed.

  • void restartSwipeController()

    Registers the swipe device. Should only be called after calling stopSwipeController()

  • String getDefaultMsg()

    Returns the default message for the current device state.

PGSwipeEnterprise extends PGSwipeDevice

This class handles communications with the iPS Enterprise Encrypted Mobile Card Reader.

  • void InitializeReader(Context ctx)

    This class is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create a PGSwipeEnterprise instance to interact with the iPS Enterprise device.

PGSwipeIPS extends PGSwipeDevice

This class handles communications with the iPS Encrypted Mobile Card Reader.

  • void InitializeReader(Context ctx)

    This class is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create a PGSwipeIPS instance to interact with the IPS device.

PGSwipeUniMag extends PGSwipeDevice

This class handles communication with the IDTECH Unimag device.

  • void InitializeReader(Context ctw)

    This class is not intended to be instantiated directly. Instantiate a PGSwipeController instead. The PGSwipeController will create an instance of PGSwipeUniMag to interact with the Shuttle device.

  • void updateCompatableDeviceList()

    The UNIMAG device uses an xml compatibility list that consists of specific device settings that are unique to every device. This function should be called to handle new devices.

PGCard

This is a simple base class for the different types of cards that can be used. There is no reason to ever explicitly declare this.

  • void setCVV(String CVV)