The @Pay JavaScript SDK allows you to safely register @Pay accounts, tokenize Credit Card records and run Transactions. To include the SDK in your site (for all environments), use:
<script type="text/javascript" src="https://dashboard.atpay.com/sdk/v3.js"></script>
In order to accept payments or register cards successfully with the @Pay JS SDK, your Customer should be using IE8+, Chrome, Firefox 3+, Safari 5.1+ (OSX / iOS) and must have Javascript enabled.
The SDK is loaded by placing the script element at the end of the body element:
Please load jQuery (>= 1.9.1) independently of the SDK:
<html> <head> <title>Example</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> </head> <body> <script type="text/javascript" src="https://dashboard.atpay.com/sdk/v3.js"></script> <script type="text/javascript"> $(function(){ atpay.config({ partner_id: PARTNER_ID }); }); </script> </body> </html>
Copy - Expand
Set up the default configuration values for future method calls. You must call this method before using any other JS SDK calls.
Attribute | Description |
---|---|
partner_id | The partner id given to you by @Pay |
access_token | This is the access token for the current customer if you have one (optional) |
Register a new card for use. If this is the initial registration of a card, it is possible to optionally create a transaction on behalf of that Customer.
atpay.register(form, callback) Register a new card. Creates a new credit card record with @Pay and provides a token which can be used for future transactions against it. If the form contains a field called ‘amount’, @Pay will also process a transaction for this amount.
Argument | Description |
---|---|
form object | The form element on your page that accepts card information, or a javascript object containing the card details by name |
callback | Function to call when the card registration fails or succeeds |
After a card has been successfully registered, you will receive the following information in the response argument to your callback function.
Attribute | Details |
---|---|
atpay_token | The reference used to charge this card in the future. You should store this value safely on your server |
referrer_context | The value you passed through the registration process |
signature | Please see the “Verification” section below |
transaction | If you specified an amount, the corresponding transaction |
{ atpay_token: "XYZ", message: "registration_response", referrer_context: "sku-11", signature: "a5ac216fd6d43c424da4e743291ac01e87b9a414" transaction: { balance: "40.0", created_at: "2013-08-12 00:00:00 -0600", fee: "0.0", id: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", signature: "b6bd327ge7e53c424da4e33256adccf82lsla1xy" } }
Copy - Expand
Since the client can easily falsify information you act upon within the browser, you must assume that the transaction confirmation you’ve received in your callback function is tampered. If you rely on the @Pay email messaging and don’t redeem the transaction for a good without subsequent confirmation from the @Pay hook, you don’t need to worry about this. If you need to provide your Customers with immediate confirmation and deliver a good directly (digital goods and downloads), we recommend you check the signature value of the response.
The signature on a successful registration is the HMAC-SHA1 hex digest value of the returned credit card token signed with your private key. Verify this on your server (note that the transaction on the response object will not exist if you don’t perform a transaction on the registration request):
$.post("/token/verification", { signature: response.signature, transaction_id: response.transaction.id, transaction_signature: response.transaction.signature, transaction_balance: response.transaction.balance, token: response.atpay_token, }, function(response){ if(response.status == 'ok'){ alert("OK"); }else if(response.status == 'fail'){ alert("FAIL"); } });
Copy - Expand
And on the server (sample in ruby):
require 'openssl' # ... digest = OpenSSL::HMAC.hexdigest("sha1", ATPAY_PRIVATE_KEY, params[:token]) transaction_digest = OpenSSL::HMAC.hexdigest("sha1", ATPAY_PRIVATE_KEY, "#{params[:transaction_id]}/#{params[:transaction_balance]}") if digest == params[:signature] and transaction_digest == params[:transaction_signature] render :json => { :status => "ok" } else render :json => { :status => "fail" } end # ...
Copy - Expand
<script type="text/javascript"> // For initial registration. $(document).ready(function() { $("#form-id").submit(function(e) { e.preventDefault(); atpay.register("#form-id",function(response){ // validate response }); }); }); // For updating a registered card. $(document).ready(function() { $("#form-id").submit(function(e) { e.preventDefault(); atpay.update("#form-id",function(response){ // validate response }) }); }); </script>
Copy - Expand
Process transactions from a web site using the card token returned in the registration call.
The sale call uses a provided amount and card token to process a transaction.
Parameter | Description |
---|---|
amount/token | Numeric amount of the transaction in dollars |
callback | A javascript function to call when the sale has succeeded or failed |
options | Javascript Object with additional parameters, ‘card’ is a required value, and ‘referrer_context’ is a value you wish to store with the transaction data |
Function(response), where response is an object with the following structure:
Attribute | Description |
---|---|
id | The @Pay database identifier for this transaction |
balance | The final amount for the transaction |
fee | The fee amount taken for this transaction |
disbursement_date | The date on which this transaction was disbursed |
created_at | The timestamp when the transaction was created |
updated_at | The timestamp when the transaction was last updated |
On a transaction success, you will receive the following response object as an argument to your callback (response).
{ id: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", balance: 10.0, fee: 0.0, disbursement_date: null, signature: "a5ac216fd6d43c424da4e743291ac01e87b9a414", created_at: "2013-03-15T14:19:35-06:00", updated_at: "2013-03-15T14:19:35-06:00" } referrer_context: supplied_value
Copy - Expand
Since a User may falsify information you act upon within the browser, you must assume that the transaction confirmation you’ve received in your callback function is tampered.
If you rely on the @Pay email messaging and don’t redeem the transaction for a good without subsequent confirmation from the @Pay hook, you don’t need to worry about this. If you need to provide your Customers with immediate confirmation and deliver a good directly (digital goods and downloads), we recommend you check the signature value of the response.
The signature on a successful Transaction is the HMAC-SHA1 hex digest value of the returned Transaction Id and Transaction Balance signed with your Merchant’s Private Key. Verify this on your server:
$.post("/transaction/verification", { signature: transaction.signature, id: transaction.id, balance: transaction.balance }, function(response){ if(response.status == 'ok'){ alert("OK"); }else if(response.status == 'fail'){ alert("FAIL"); } });
Copy - Expand
And on the server (sample in ruby):
require 'openssl' # ... digest = OpenSSL::HMAC.hexdigest("sha1", PRIVATE_KEY, "#{params[:id]}/#{params[:balance]}") if digest == params[:signature] render :json => { :status => "ok" } else render :json => { :status => "fail" } end # ...
Copy - Expand
<script type="text/javascript"> $(function(){ $("form").submit(function(){ atpay.sale(55.00, function(response){ // validate response }, { card: "XYZabc", referrer_context: "ref-code-0" }); }); }); </script>
Copy - Expand
Invoices are emails generated and sent by @Pay. They contain two-click transaction over email for the amount and items specified.
atpay.invoice will generate an invoice that can be fulfilled by any email adress.
atpay.targeted_invoice will generate an invoice that can only be fulfilled by the receiving email.
Structure |
---|
atpay.invoice(email, subject, message, items, properties, callback); |
Arguments | Description |
---|---|
The email address you would like to invoice. If is a targeted_invoice, transactions will only succeed with this address. | |
subject | The subject of the email that the invoice will generate. This will also be the default offer name. |
message | A string of text to be included in the invoice email. |
items | An array of items that make up the offer. See below. |
properties | An optional hash of additional token methods. See below. |
callback | Callback function |
Items | Description |
---|---|
name | Name of an individual included in the invoice |
amount | Numeric amount of the item in dollars |
quantity | An integer value representing the number of items being purchased. |
Properties | Description |
---|---|
requires_shipping_address | A boolean value that sets whether or not to require shipping info |
requires_billing_address | A boolean value that sets whether or not to require billing info |
shipping_address | A JS object with shipping details |
billing_address | A JS object with billing details |
item_details | A string value that sets the details or description of generated token |
name | A string value that sets the name of the token. |
item_quantity | An integer value that sets the amount of times the invoice can generate a successful transaction. Must use @Pay’s pre-sale hook. |
estimated_fulfillment_days | If the token is set to auth only, this is the amount of time it will take to capture the transaction. |
auth_only | A boolean value that if set to true will only authorize funds. Set estimated_fulfillment_days to capture the transaction. |
url | A valid url that will be used for a custom signup page. |
expires_in_seconds | The number of seconds the token will expire after generated. |
request_custom_data | A JS object containing ‘name’ and ‘required’ that will generate custom fields if using the hosted payment page. ex {name:”custom_field”, required: true} |
The callback function response
parameter describes the invoice:
{ "invoice":{ "uuid": "99143BA5-C4BF-46D6-A2FA-6B868AE6E4C6" "message": "Your Order Description", "subject": "Your Order Title", "created_at": "2014-08-25T10:55:47-06:00", } }
Copy - Expand
Hooks for invoice-based transactions contain the invoice_uuid
parameter
within user_data
:
{ ... "user_data": { "invoice_uuid": "99143BA5-C4BF-46D6-A2FA-6B868AE6E4C6" } ... }
Copy - Expand
var email = "customer@example.com"; var title = "Your Order Title"; var description = "Your Order Description"; var breakdown = [ { name: "Some Item", amount: 25.0, quantity: 2 }, { name: "Some Shipping", amount: 30.0, quantity: 1 } ]; var properties= { requires_shipping_address : true, shipping_address : {street: "123 Shipping", ... } request_custom_data : [{name: "field_name", required: true}, {name: "another", required: false}] }
Copy - Expand
Calling atpay.invoice
delivers the invoice:
atpay.invoice(email, title, description, breakdown, properties, function(response){ var invoice = response.invoice; var invoice_uuid = invoice.uuid; });
Copy - Expand
Calling atpay.targeted_invoice
delivers an invoice that can only be processed by the receiving email:
atpay.targeted_invoice(email, title, description, breakdown, properties, function(response){ var invoice = response.invoice; var invoice_uuid = invoice.uuid; });
Copy - Expand
If a transaction or card registration fails, your callback function will receive an object in the response argument with the error that occurred.
Error Type | Description |
---|---|
fatal | This type indicates that the sure should not attempt to commit the transaction again, and should contact customer service for support. |
error | This type indicates that the customer should attempt the transaction again, using the attached messages as a guide for what needs correction. |
ok | This type will not be seen in the error condition. |
*error.general# This represents a general failure message, which you could display, for example, near the top of the form for the customer who ran the transaction to read.
Specific errors for the attribute are mapped to the name given in the data-atpay attribute. You can use this information to alter your form state by examining each of these keys. We recommend iterating through each input type with a data-atpay attribute to check for applicable attributes instead of iterating through the response object.
You can generate a range of unanticipated execution exceptions in the sandbox by sending requests with specific amounts. Below is a table with the amounts and the errors they generate.
Amount | Error |
---|---|
3550.00 | Card Expired |
3551.00 | Insufficient Funds |
3552.00 | Unspecified System Exception |
3553.00 | Processing Server Timeout |
3554.00 | Processing Service Timeout |
3555.00 | AVS Failure |
3556.00 | Bank Authorization Required |
3557.00 | General Unspecified Decline |
3558.00 | Card Stolen |
3559.00 | Issuing Bank System Unavailable |
3560.00 | Inactive Card or Online Purchase Disabled |
3561.00 | Credit Limit Reached |
3362.00 | Invalid CVN |
3563.00 | Processor Denial |
3564.00 | Invalid CVN |
3565.00 | General Unspecified Decline |
3566.00 | Processing Server Timeout |
3567.00 | Authentication Failure |
3566.00 | General Failure |
Execute a $30.05 transaction with a reference code sku123. If there’s an error, alert with the error details.
{ error: { type: "fatal", general: "Could not charge card", cvc: "is invalid" } }
Copy - Expand
The form you implement to accept credit card information is hosted on your site. @Pay’s SDK will wrap your form submission process to first post sensitive information to our PCI compliant servers, and then removes that information from your form so you can submit it to your server:
Since @Pay’s SDK is designed to work with your existing forms, we understand that the names of your fields may differ from @Pay’s expectations. Instead of using the name attribute, @Pay’s SDK uses the data-atpay attribute to determine the name of a field.
Any input field without a name attribute is not submitted to your server when a customer clicks ‘Post’, but as an additional safeguard, adding the data-atpay-protected attribute will ensure that @Pay’s SDK removes the form element prior to submission.
The trickiest part of integrating @Pay into an existing form is the form validation you already have. We recommend providing full client-side form validation, and handling server-side form validation errors carefully with the knowledge that a transaction may have occurred.
Your client-side validation should be performed first, and then the atpay.register method should be called after validation is successful. If an error is encountered, you can push this error into your validation framework to display the proper messaging to the customer. Otherwise, submit to the server.
data-atpay value | @Pay Format | Constraints | Protected |
---|---|---|---|
first_name | Card Holder’s First Name | 255 character maximum (required) | |
last_name | Card Holder’s Last Name | 255 character maximum (required) | |
Card Holders’ Email Address | regex: .+@.+ | ||
street | Billing Address | 255 character maximum | |
street2 | Billing Address Line 2 | 255 character maximum | |
city | Billing City | 255 character maximum | |
state | Two digit state abbreviation | Two digit abbreviation (http://en.wikipedia.org/wiki/List_of_U.S.state_abbreviations#ANSI_standard_INCITS38:2009) | |
zip | Billing zip code | Five digit numerical, regex: .+@.+ | |
country | Billing country | Only “United States” accepted | |
phone | Billing phone number | Ten Digits (ex: 5551234567) | |
amount | Sale/purchase amount | Numerical string regex: d+(.d{2}) | |
referrer_context | Extra data you wish to pass | 2500 character maximum | |
card_number | Credit Card Number | ex: 4111111111111111 | YES |
exp_month | Card Expiration Month | Two numerical digits (ex: 04) | |
exp_year | Four digit expiration year | Four numerical digits (ex: 2017) | |
cvc | Card security code | ex: 123 | YES |
<form action="/submit" method="POST" id="registration-form"> <!-- phone number is passed to @Pay as 'phone', and to your server as 'phone_number' --> <input type="text" name="phone_number" data-atpay="phone" /> <input type="text" name="first" data-atpay="first_name" /> <input type="text" name="last" data-atpay="last_name" /> <input type="text" name="email" data-atpay="email" /> <input type="text" name="street" data-atpay="street" /> <input type="text" name="city" data-atpay="city" /> <input type="text" name="state" data-atpay="state" /> <input type="text" name="zip" data-atpay="zip" /> <input type="text" name="country" data-atpay="country" value="United States" /> <input type="text" name="phone" data-atpay="phone" /> <input type="text" data-atpay="card_number" data-atpay-protected="true" /> <input type="text" data-atpay="card_type" /> <input type="text" data-atpay="exp_month" /> <input type="text" data-atpay="exp_year" /> <input type="text" data-atpay="cvc" data-atpay-protected="true" /> <input type="submit" /> </form>
Copy - Expand
<head> <title>Example</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script> <script type="text/javascript" src="https://dashboard.atpay.com/sdk/v3.js"></script> <script type="text/javascript"> $(function(){ atpay.config({ partner_id: 8004 }); }); function returnFunc(data) { alert(data); } $(document).ready(function() { $("#atpay-card").submit(function(e) { e.preventDefault(); atpay.register("#atpay-card",returnFunc) }); }); </script> </head> <body> <form action="/submit" method="POST" id="atpay-card"> <!-- phone number is passed to @Pay as "phone", and to your server as "phone_number" --> <label for="phone_number">phone_number</label> <input type="text" name="phone_number" data-atpay="phone" /> <label for="first">first</label> <input type="text" name="first" data-atpay="first_name" /> <label for="last">last</label> <input type="text" name="last" data-atpay="last_name" /> <label for="email">email</label> <input type="text" name="email" data-atpay="email" /> <label for="street">street</label> <input type="text" name="street" data-atpay="street" /> <label for="city">city</label> <input type="text" name="city" data-atpay="city" /> <label for="state">state</label> <input type="text" name="state" data-atpay="state" /> <label for="zip">zip</label> <input type="text" name="zip" data-atpay="zip" /> <label for="country">country</label> <input type="text" name="country" data-atpay="country" value="United States" /> <label for="phone">phone</label> <input type="text" name="phone" data-atpay="phone" /> <label for="card-number">card-number</label> <input type="text" data-atpay="card_number" data-atpay-protected="true" /> <label for="card_type">card_type</label> <input type="text" data-atpay="card_type" /> <label for="exp_month">exp_month</label> <input type="text" data-atpay="exp_month" /> <label for="exp_year">exp_year</label> <input type="text" data-atpay="exp_year" /> <label for="cvc">cvc</label> <input type="text" data-atpay="cvc" data-atpay-protected="true" /> <input type="submit" /> </form> </body> </pre>
Copy - Expand