Skip to main content

Sunbit Checkout SDK

Overview#

The Sunbit Checkout integration adds Sunbit as a payment method for your customers to buy now, pay-over-time.

There are five steps for integrating Checkout using our SDK:

  1. Integrate the Server

  2. Add and initialize the Sunbit SDK

  3. Using the Sandbox

  4. Switch to Production Mode

Once the steps above have been completed, your Sunbit Online integration will work as follows:

  1. At checkout, Customers can select "Checkout with Sunbit" and click the checkout button.

  2. The checkout button will call your server with the details of the transaction.

  3. Using the transaction details provided in Step 2, your server calls the Sunbit API, initiates a transaction and receives a token.

  4. With the token, a modal is opened using the SUNBIT.epay.checkout function. This allows the customer to complete the transaction with Sunbit.

  5. After the transaction is complete, the transaction completion status is validated using the validation API.

Integrate the Server#

A server integration provides more security and stability when you process transactions with Sunbit. The integration with the Sunbit Online server will result in calls being made from your server to the Checkout SDK.

Initialization call#

To initiate a transaction and receive a token (the token will need to be provided later to initialize the e-Pay with the SDK) call the Sunbit server at https://api-sandbox.sunbit.com/epay/api/v1/epay from your server using the POST method.

Please include representative details such as id, name and email which will enable Sunbit to improve the experience for associates and help them close more transactions.

You will need to provide the following:

Request Headers:

AttributeRequiredTypeDescription
sunbit-keyyestextProvided to you by Sunbit - keys are different between sandbox and production environments
sunbit-secretyestextProvided to you by Sunbit - secrets are different between sandbox and production environments
content-typeyestextOnly application/json is accepted

Body#

AttributeRequiredTypeDescription
transactionIdyestextYour internal id for the current transaction
amountyesnumberThe current transaction total amount (up to 2 decimals)
locationyestextYour location name as provided by Sunbit
referenceNumbersee DesctextProvided to you by Sunbit if necessary. This field is otherwise not required.
departmentNamenotextProvided to you by Sunbit - the department in which the transaction is taking place
customerDetailsnoCustomerDetailsThe customer details which will be prepopulated in the Sunbit application
shippingAddressnoShippingAddressThe customer shipping Address which will be prepopulated in the Sunbit application
isShippingToStorenobooleanIndicator used to determine if the item is being shipped to a store. Value is set to ‘false’ by default
itemsnoItem[]An array of Item(s) - see Item
representativeEmailnotextEmail address of the representative/associate.

CustomerDetails#

Important

Merchants from the following states are not supported: VT, WV and WY. Business information of Dental and Medical Spa Merchants/Customers located in CA will not be pre-filled.

AttributeRequiredTypeDescription
firstNamenotext
lastNamenotext
emailnotext
phonenotext10 digits
dateOfBirthnotextFormatted as yyyy-mm-dd
addressDetailsnoAddressDetails

ShippingAddress#

AttributeRequiredTypeDescription
street1notextCustomer’s shipping street name
citynotextCustomer's shipping city
statenotextCustomer's shipping state
zipCodenotextCustomer's shipping zipcode

AddressDetails#

AttributeRequiredTypeDescription
addressnotextCustomer's address
citynotextCustomer's city
statenotextCustomer's state
zipCodenotextCustomer's zipcode

Item#

AttributeRequiredTypeDescription
serialNumberyestext
amountyestextUp to 2 decimals

Response#

AttributeTypeDescription
tokentextTo be used in the checkout modal
## Initialization Call Example:## Request:curl -X POST \  '"https://api-sandbox.sunbit.com/epay/api/v1/epay' \  -H 'Content-Type: application/json' \  -H 'sunbit-key: YOUR_KEY' \  -H 'sunbit-secret: YOUR_SECRET' \  -d '{    "transactionId": "000000931",    "amount": 1008,    "location": "Location1",    "referenceNumber": "prq-534-1234-212",    "representativeEmail": "jason@email.com",    "customerDetails": {        "firstName": "John",        "lastName": "Doe",        "email": "john.doe@emailaddress.email",        "phone": "303-988-8945",        "addressDetails": {            "address": "2491  Tavern Place ",            "city": "Lakewood",            "state": "CO",            "zipCode": "80227"        }    },        "shippingAddress": {        "street1": "831 Kipling St",        "city": "Lakewood",        "state": "CO",        "zipCode": "80215"    },    "isShippingToStore": false    "items": [        {            "serialNumber": "1111111",            "amount": 166        }    ]}'
## Response: JWT{  "token" : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRob3JpdGllcyI6WyJST0xFX09OTElORV9DVVNUT01FUiJdLCJqdGkiOiJmMmQ0YWZhYy1hYjk3LTRmOTEtYTM1MS00NTUxODkzNjQ4MTgiLCJzY29wZSI6WyJlcGF5Il0sImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjp7InJldGFpbGVySWQiOiIxIiwiYWxsaWFuY2VJZCI6IjEiLCJ0cmFuc2FjdGlvbklkIjoiY29tcGxldGVkLXU3ejN0Yk0zNnUiLCJhbW91bnQiOiIxMDA4LjAifSwiZXhwIjoxNTU3MjM4NjU4LCJjbGllbnRfaWQiOiJlcGF5LXNlcnZpY2UifQ.w5djYV5n2Pl1-7g3KRw2UDtuV0r2PirPC7x4kRQCsiwxRZ3wnnb44kaPvoVHNhiWoU1vQo8dYCnM9sjXZ5juKpHSWjnXZzD-Wzyv2ZCAmJS5wMBzbTsZicRDuqZO9QTSLzZb8ahaenRDUw4rUwhvKaOCzDMTn5rHVMq3NHyynJA-zwF1hITlcZs_KIuZN6pW8wGRldprm5It0C0NqSMiItDmJS0dh0xAhtkLgy266-MwbdNyk_habI-SuY9Vu5U9UwtUtDIQxKbHJuXu6G-PET5JDA0K90GJkG9wyQXs2miFFEkq9gEcYbpWpZBPD5tq0fJZyLd5roVutJFp3skoCA"}

Errors:#

Error CodeMessageDescription
403Bad credentialsSunbit key or secret is wrong
403IP address is not allowed for this sunbitKeyIP address does not match account
404Location does not existProvided location does not match account
422Number of epays for sunbitKey: [sunbitKey] passed the daily limitNumber of calls passed the daily limit
422Amount should be greater than 0Transaction amount should be greater than 0
422Customer reference number is invalidReference number for the pre-qualification process is invalid or expired
422Email address is not validInvalid representative email address
500Internal Server ErrorSomething went wrong on Sunbit's side

Validation call#

When it's time to validate the transaction result (for example after the Sunbit window has closed) call the Sunbit server at https://api-sandbox.sunbit.com/epay/api/v1/epay from your server using the GET method.

You will need to provide the following parameters:

Request Headers:

AttributeRequiredTypeDescription
sunbit-keyyestextProvided to you by Sunbit
sunbit-secretnotextProvided to you by Sunbit

URL query parameters:

AttributeRequiredTypeDescription
purchaseIdyestextThe purchase Id that is generated by Sunbit and returned in the e-Pay SDK after a successful Sunbit flow has been completed and the onCompleted callback was called. Any other purchase Id will result with status incomplete
transactionIdnotextYour internal id for the current transaction, should be the same as you provided during the initialization call

Response fields Types:#

AttributeTypeDescription
purchaseIdtextThe purchase Id that is generated by Sunbit and returned in the e-Pay SDK after a successful Sunbit flow has been completed. Might be null in the case of INCOMPLETE status (when sunbit flow didn't start, for any reason)
purchaseAmountdecimalThe transaction total amount. Might be null in the case of INCOMPLETE status (when sunbit flow didn't start, for any reason)
status[COMPLETED INCOMPLETE VOIDED]COMPLETED - The transaction is successful.
INCOMPLETE - The transaction is still in progress.
VOIDED - The transaction has been canceled
purchaseDatedate

YYYY-MM-DD'T'hh:mm:ss
The date and time when sunbit flow started. Might be null in the case of INCOMPLETE status (when sunbit flow didn't start, for any reason)

Validation Call Example:#

## Request:curl 'https://api-sandbox.sunbit.com/epay/api/v1/epay?transactionId=completed-gthftredxserrr&purchaseId=39325178' \  -H 'sunbit-key: YOUR_KEY' \  -H 'sunbit-secret: YOUR_SECRET'

## Response:{  "purchaseId": "mockId",  "purchaseAmount": 100,  "status": "COMPLETED",  "purchaseDate": "2020-06-16T01:02:42"}

Errors:#

Error CodeMessageDescription
403Forbidden purchaseId / transactionIdTransaction / purchase id does not belong to account
403Bad credentialsSunbit key or secret is wrong
403IP address is not allowed for this sunbitKeyIP address does not match account
500Internal Server ErrorSomething went wrong on Sunbit's side

Simulate completion status in sandbox#

In order to simulate a completion status to test responses other than completed, you can add one of the following prefixes below to the transactionId.

PrefixStatus CodeTransaction completion status
TRANSACTION_NOT_ALLOWED e.g. TRANSACTION_NOT_ALLOWED_ve3bbr403Transaction id does not belong to an account
PURCHASE_NOT_ALLOWED e.g. PURCHASE_NOT_ALLOWED_ve3bbr403Purchase id does not belong to an account
BAD_CREDENTIALS e.g. BAD_CREDENTIALS_ve3bbr403Sunbit key or secret is wrong
IP_NOT_ALLOWED e.g. IP_NOT_ALLOWED_ve3bbr403IP address does not match an account
WRONG_PURCHASE e.g. WRONG_PURCHASE_ve3bbr422The given purchaseId is not recognized as an existing purchase in the system
INTERNAL e.g. INTERNAL_ve3bbr500Something went wrong on Sunbit's side

For example, in order to simulate passing wrong sunbit key or secret:

## Validation Call Example:## Request:curl 'https://api-sandbox.sunbit.com/epay/api/v1/epay?transactionId=BAD_CREDENTIALS_ve3bbr' \  -H 'sunbit-key: YOUR_KEY' \  -H 'sunbit-secret: YOUR_SECRET'

## Response:{    "message": "Bad credentials",    "code": "forbidden"}

Add and initialize the Sunbit SDK#

The Sunbit SDK for JavaScript doesn't require any standalone files to be downloaded or installed. Instead, you simply need to include a short piece of JavaScript into your HTML that will asynchronously load the SDK into your pages. The async load means that it does not block loading other elements in your page. The following snippet of code (Snippet #1) will give the basic version of the SDK where the options are set to their most common defaults. You should insert it on each page you want to load it, directly after the opening tag.

Init Sunbit's SDK#

<script>  // Init Sunbit SDK   window.sunbitAsyncInit = function() {     SUNBIT.init({       mode: 'SANDBOX',       sunbitKey: <Your Sunbit key> //Supplied by Sunbit - NOTICE: Do not insert your secret here     });   }; </script><script async defer src="https://static.sunbit.com/sdk/sunbit-sdk.js"></script>

Add Sunbit Checkout to your page

After adding the Sunbit SDK to your site and initializing it, you can add the Sunbit Checkout element to your checkout page using the method detailed below as snippet #2.

<script>  // Add a checkout element  SUNBIT.UI.checkoutElement('[data-sunbit-checkout]', {    theme: 'transparent',    size: 'large',  });</script>

The method accepts the following:

ParamTypeDescription
Element Id or selectortextContainer element
optionsCheckoutElementOptionsContains theme, size, see Options

CheckoutElementOptions:

optionRequired?typeDefaultDescription
sizenotext"medium"("small", "medium", "large") Size of the rendered button
themenotext"dark"("dark", "light", "white", "transparent") Colors/theme of the button

Set up the payment method on your site#

  1. Add a function call to your checkout button, which is called when a customer selects the "Checkout with Sunbit" option.
  2. The method should call your server's initiate transaction API (as stated above) with the transaction details. Your server should return the token returned by Sunbit's initialization API.
  3. Call the checkout method of the SDK to start the checkout process using the token and callback methods.

The checkout method accepts the following

ParamTypeDescription
CheckoutOptionsObjectObject containing the token generated in the server to server call and the callback functions.

CheckoutOptions:

OptionRequired?TypeDescriptionResponse
tokenyestextThe token generated in the server to server call
onCompletednoFunctionA function Sunbit will call when the user transaction has been completed and the iFrame is closed
  • checkoutContext: text
  • page; From the enum as stated below
  • type: text
  • purchaseId; Sunbit’s purchase id for use in validation call
onCancelednoFunctionA function Sunbit will call when the user transaction has been completed unsuccessfully
  • checkoutContext: text
  • type: text
  • purchaseId; Sunbit’s purchase id for use in validation call
onUserCancellednoFunctionA function Sunbit will call when the user transaction has been cancelled by the user
  • checkoutContext: text
  • type: text
  • purchaseId; Sunbit’s purchase id for use in validation call
onPlaceInFlownoFunctionA function Sunbit will call when a page changes in the epay flow
  • type: text
  • page; From the enum as stated below
  • purchaseId; Sunbit’s purchase id for use in validation call
onPurchaseVerifiednoFunctionA function Sunbit will call when the user purchase has been verified
  • checkoutContext: text
  • type: text
  • purchaseId; Sunbit’s purchase id for use in validation call

Place in flow callback#

This callback returns information on each step the customer has reached within the Sunbit flow. Register to onPlaceInflow to receive an eNum representing the last screen the customer has entered. Note that for different reasons, the eNum can repeat itself within a single flow and that the last callback is always the accurate position.

Current pages enum:#

  • PHONE_NUMBER
  • PHONE_VERIFICATION
  • CUSTOMER_DETAILS
  • EMAIL_VERIFICATION
  • APPROVAL
  • PAYMENT_PLAN
  • PAYMENT_METHOD
  • AGREEMENT
  • AUTHORIZATION
  • THANK_YOU
SUNBIT.epay.checkout({  token: data.sunbitToken, // should be generated by server to server  onCompleted: (data) => {    handleCompleted(data.statusType, data.purchaseId); // handleCompleted - your function  },  onCanceled: (data) => {    handleCancellation(data.statusType); // handleCancellation - your function  },  onUserCancelled: (data) => {    handleUserCancellation(data.statusType); // handleUserCancellation - your function  },  onPlaceInFlow: (data) => {    handlePage(data.page); // handlePage - your function, page- enum as stated above  },  onPurchaseVerified: (data) => {    handlePurchaseVerified(data.purchaseId); // handlePurchaseVerify - your function  },});

​​Usage Example#

  <script>        window.sunbitAsyncInit = function() {          SUNBIT.init({            sunbitKey      : '', //SUNBIT KEY            mode: '', // sandbox/prod - please review notes below.          });
          SUNBIT.UI.checkoutElement('[data-sunbit-checkout]', {            theme: 'transparent',            size: 'large',          });
          const button = document.querySelector('div[data-sunbit-checkout]'); // checkoutElement btn.          SUNBIT.epay.init({            onInitFinish: () => {              button.addEventListener('click',()=> {                SUNBIT.epay.checkout({                  token: '', // For the Initialization call                  onCompleted: (data) => {                    console.log(`status: ${data.statusType}, purchaseId: ${data.purchaseId}`); // handleCompleted - your function                  },                  onCanceled: (data) => {                    console.log(`status: ${data.statusType}`);                  },                  onUserCancelled: (data) => {                    console.log(`status: ${data.statusType}`);                  },                  onPlaceInFlow: (data) => {                    console.log(`page: ${data.page}`);                  },                  onPurchaseVerified: (data) => {                    console.log(`purchaseId: ${data.purchaseId}`);                  },                });              });            }          })        };  </script>  <script async defer src="https://static.sunbit.com/sdk/sunbit-sdk.js"></script>

Notes:

  1. SDK INIT configuration mode: You can choose between sandbox/prod values - please view: Using the sandbox and Switch to Production Mode
  2. The token for SUNBIT.epay.checkout is provided in the Initialization call
  3. Keep in mind that the event listener for this button should be after onInitFinish.
  4. When importing the sunbit-sdk, make sure that you are using async defer.

​​Using the Sandbox#

The default mode of the SDK is "sandbox", which is meant to be used for server integration testing.

Important: In order to receive a real and working purchase ID you will need to switch to "demo" mode. You will need a purchase ID to test the end-to-end integration with the server before moving to production. See "Full flow simulation" below.

Minimal flow simulation#

In this mode we simulate the iframe and completion of Sunbit's flow only, there are no calls being made to Sunbit's servers and it is meant only to provide a simulation for developers to check the javascript integration and callbacks without the need of completing a full flow.

Once initiated you should see a screen similar to this

Simulation

This mode is intended to help with server integration and making sure the initialization and the completion of the transaction are working properly.

You can control the completion status of the transaction by prefixing your transaction ID as follows:

In sandbox mode, add one of the prefixes below to the transactionId to simulate a response with a specific status from Sunbit's server:

PrefixStatus CodeTransaction completion status
COMPLETED e.g. COMPLETED\_3423lgregr200Transaction COMPLETED successfully
INCOMPLETE e.g. INCOMPLETE\_bre45ge3f200Transaction INCOMPLETE
VOIDED e.g. VOIDED\_ve3bbr200Transaction is VOIDED
BAD_CREDENTIALS e.g. BAD\_CREDENTIALS\_ve3bbr403Sunbit key or secret is wrong
IP_NOT_ALLOWED e.g. IP\_NOT\_ALLOWED\_ve3bbr403IP address does not match the account
LOCATION_NOT_EXIST e.g. LOCATION\_NOT\_EXIST\_ve3bbr404Provided location does not match the account
DAILY_LIMIT e.g. DAILY\_LIMIT\_ve3bbr422Number of calls passed the daily limit
LOW_AMOUNT e.g. LOW\_AMOUNT\_ve3bbr422Transaction amount should be greater than 0
INTERNAL e.g. INTERNAL\_ve3bbr500Something went wrong on Sunbit's side

Full flow simulation#

Once done with the integration, you can see the full Sunbit flow by changing the mode to "demo".

During the flow you will be prompted to enter customer details. See below for guidance:

ElementValue
Phone Number
  • Any: text messages will not be sent in demo mode
  • 212.555.9999: email-verified simulation
  • Previously used phone numbers: email-verified simulation
Pin code1234
Customer name, address, details
  • Any
  • Customer age: 18 years or older
  • SSN: any
EmailAny; use a real email address that you can verify as a verification email will be sent to that email address
Debit card and bank informationAny; information is not stored

Notice

  1. Customer details, e.g. name, email, phone number, are saved in the demo environment, so once you entered details for a certain phone number, the next time you use it, the same details will load again.
  2. The default pin code for SMS verification is 1234.
  3. An email verification will be sent to the email provided and will need to be verified in order to continue the flow.
<script>        window.sunbitAsyncInit = function() {          SUNBIT.init({            sunbitKey      : '<YOUR SUNBIT_KEY>', //mandatory, provided by Sunbit            mode           : 'demo',            location       : '<YOUR LOCATION NAME>', //optional            representative : '<REPRESENTATIVE>', //optional            ro: '<RO>' //optional          });        };      </script>

Switch to Production Mode#

Server-side changes#

  1. Replace the demo api URL calls with the production URL: https://api.sunbit.com/epay/api/v1/epay
  2. Change to production values: sunbit-secret, sunbit-key, Location
  3. Cleanup any prefixes you might have added to your transactionIds during development.

Client-side changes#

  1. Change mode in SUNBIT.init function to "prod"
<script>        window.sunbitAsyncInit = function() {          SUNBIT.init({            sunbitKey      : '<YOUR SUNBIT_KEY>', //mandatory, provided by Sunbit            mode           : 'prod',            location       : '<YOUR LOCATION NAME>', //optional            representative : '<REPRESENTATIVE>', //optional            ro: '<RO>' //optional          });        };</script>