JS Developer Guide

Introduction

This page walks developers through the process of accepting an EBT payment using Forage's JS SDK. We will look at the different flows you will need to implement for,

  1. Tokenizing an EBT Card
  2. Performing a balance check
  3. Capturing a payment

Installation

Install the SDK by either inserting the appropriate script tag:

<script type="text/javascript"
    src="https://prod-forage-sdk.s3.us-west-2.amazonaws.com/versions/0.1.23/sdk.js"
    charset="utf-8">
</script>

Or, by installing the npm package:

npm install forage-js-sdk

You can then import the SDK as:

import { ForageCardCapture, EbtCard } from 'forage-js-sdk'

Tokenize an EBT Card

In order to process an EBT payment, your application first needs to tokenize the EBT card using Forage's vault. You will use the ForageCardCapture class to instantiate a secure card capture <iframe>. Your success callback should store the tokenized EBT card in the wallet functionality of your application.

Creating the ForageCardCapture

Add a <div> with a unique id for the CardCapture ForageFrame to your application.

Pass the id to the ForageCardCapture constructor. When called, the constructor uses the id to insert a secure <iframe> at the <div>. This <iframe> contains a single input field where the customer inputs their EBT card number.

The below example passes the id forage-card-capture-div to the constructor:

import { ForageCardCapture } from 'forage-js-sdk'

const options = {
  successColor: '#4F8A10',
  errorColor: '#D8000C',
  placeholder: '4111 1111 1111 1111',
}

const cardInput = new ForageCardCapture(
  'forage-card-capture-div',
  'sandbox',
  options
)

๐Ÿ“˜

Supply a unique id for each ForageFrame in your application.

Card Number Validations

The ForageCardCapture <iframe> performs appropriate validations on the card number entered by your customer. When the form is displayed, your user will receive visual feedback on the validity of the card number.

Submitting the form

Whenever the user clicks the submit button, you simply need to call cardInput.submit, after which the SDK will attempt to tokenize the card and then call the appropriate callback function.

let paymentMethodRef = ''

const handleForageCardInputSuccess = (statusCode, response) => {
  paymentMethodRef = response.ref
}

const handleForageCardInputError = (errorResponse) => {
  const { httpStatusCode, code, message } = errorResponse.errors[0]
  // In general, `message` is developer-facing and should not be displayed directly to customers.
  console.error(message)
}

cardInput.submit(
  'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhIjo0LCJleHAiOjE2Njg4MDcyNDF9.oQ2LMnhfTKEp-4dIuGuh3lec87_6rhKXfSJGMYMYNPA',
  '1234567',
  (statusCode, response) => handleForageCardInputSuccess(statusCode, response),
  (errorResponse) => handleForageCardInputError(errorResponse)
)

Be sure to store the ref field in your database such that it can be reused in future transactions by the current customer. This field will be used to create Payment objects and to do balance checks.

Forage suggests that you supply a mapping of errors[0].code to specific error messages you would like to display to your customers. For a full list of possible error codes please see the Error codes documentation. In general, the messages inside errors from the Forage Payments API are meant to be developer-facing and should not be displayed directly to customers.

Perform a Balance Check

The USDA requires that your application provides customers with the ability to check their EBT card balance(s). Forage suggests that you allow a customer to check their EBT card balance as early as possible in your application flow. For example, allowing your customer to check their balance before filling their cart would prevent them from accidentally overspending their balance and needing to adjust their cart after making it to the checkout page.

Creating the ForageBalanceCapture

import { ForageBalanceCapture } from 'forage-js-sdk';

const options = {
  successColor: '#4F8A10',
  errorColor: '#D8000C',
  placeholder: '4111 1111 1111 1111',
}

const balanceCapture = new ForageBalanceCapture(
  'forage-card-capture-div',
  'sandbox',
  options
)

Once this function is called, a secure <iframe> will be inserted at the div tag with id = forage-balance-check-div. This <iframe> will contain a single input field where the customer should input their EBT card PIN.

Submitting the form

Add a submit button to your application. After your customer clicks the submit button, call balanceCapture.submit in your application. Pass the sessionToken, fnsNumber, and paymentMethodRef as parameters, in addition to callback functions that the SDK can call depending on the success or error response from the API.

Underneath the hood, the Forage SDK makes a request to the EBT processor for the customer's US state for the balance of the EBT card. Depending on the response from the API, the SDK then makes a call to either the successCallback or the errorCallback.

let snapBalance = ''
let cashBalance = ''

// successCallback
const handleForageBalanceCheckSuccess = (statusCode, response) => {
  snapBalance = response.snap
  cashBalance = response.non_snap
}

// errorCallback
const handleForageBalanceCheckError = (errorResponse) => {
  const { httpStatusCode, code, message } = errorResponse.errors[0]
  // In general, `message` is developer-facing and should not be displayed directly to customers.
  console.error(message)
}

balanceCapture.submit(
  'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhIjo0LCJleHAiOjE2Njg4MDcyNDF9.oQ2LMnhfTKEp-4dIuGuh3lec87_6rhKXfSJGMYMYNPA',
  '1234567',
  '2304587ef3',
  (statusCode, response) => handleForageBalanceCheckSuccess(statusCode, response),
  (errorResponse) => handleForageBalanceCheckError(errorResponse)
)

The value under the non_snap key corresponds to the EBT Cash balance of the EBT card. You should display this information to your customer so that they can make informed decisions about how much to spend on each balance of their EBT card.

Capture SNAP or EBT Cash Payments

Both SNAP and EBT Cash payments can be captured using the same SDK flow. At a high level, you will create one Payment object on the Forage Payments API for each form of tender on the EBT card you wish to charge. Therefore, if you wish to charge both SNAP and EBT Cash, you will need to create two Payment objects.

Similarly, you will need to display two separate <iframe>s in your application (one for SNAP and one for EBT Cash), because the USDA requires that cardholders enter their PIN separately for each transaction. In spite of this requirement, you can use one submit button to send both requests to Forage asynchronously. Therefore, although your customer will need to enter their PIN twice, they will not need to wait for SNAP payments to process and then wait for EBT Cash payments to process.

Creating a Payment Object

The first step in accepting either a SNAP or EBT Cash Payment is to create a Payment object on Forage's backend. This API call provides three key pieces of information to Forage,

  1. Which EBT Card should be charged (payment_method)
  2. Which balance of the EBT card you would like to charge (funding_type)
  3. The amount that should be charged (amount)

Creating the ForagePaymentCapture

import { ForagePaymentCapture } from 'forage-js-sdk'

const options = {
  successColor: '#4F8A10',
  errorColor: '#D8000C',
}

const snapCapture = new ForagePaymentCapture(
  "forage-snap-pin-div",
  "sandbox",
  options
)

const cashCapture = new ForagePaymentCapture(
  "forage-cash-pin-div",
  "sandbox",
  options
)

Once this function is called, secure <iframe>s will be inserted at the div tags id = forage-snap-pin-div and id=forage-cash-pin-div. These <iframe>s will contain a single input field where the customer should input their EBT card PIN.

Submitting the form

After your customer clicks the submit button, your application should call snapCapture.submit and cashCapture.submit. Underneath the hood, the Forage SDK will make a request to the EBT processor to deduct funds from the relevant balance of the EBT card (specified in the Payment object creation request). The SDK will then make a call to either successCallback or errorCallback with the response from the Forage Payments API.

const handleSnapForageSuccessResponse = (statusCode, response) => {
  if (response.status === 'succeeded') {
    console.log('SNAP Payment Succeeded!')
  }
}

const handleCashForageSuccessResponse = (statusCode, response) => {
  if (response.status === 'succeeded') {
    console.log('Cash Payment Succeeded!')
  }
}


const handleSnapForagePaymentError = (errorResponse) => {
  const { httpStatusCode, code, message } = errorResponse.errors[0]
  // In general, `message` is developer-facing and should not be displayed directly to customers.
  console.error(message)
}

const handleCashForagePaymentError = (errorResponse) => {
  const { httpStatusCode, code, message } = errorResponse.errors[0]
  console.error(message)
}

snapCapture.submit(
  'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhIjo0LCJleHAiOjE2Njg4MDcyNDF9.oQ2LMnhfTKEp-4dIuGuh3lec87_6rhKXfSJGMYMYNPA',
  '1234567',
  '58ce5024bc',
  (statusCode, response) => handleSnapForageSuccessResponse(statusCode, response),
  (errorResponse) => handleSnapForagePaymentError(errorResponse)
)

cashCapture.submit(
  'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhIjo0LCJleHAiOjE2Njg4MDcyNDF9.oQ2LMnhfTKEp-4dIuGuh3lec87_6rhKXfSJGMYMYNPA',
  '1234567',
  '038c7817bd',
   (statusCode, response) => handleCashForageSuccessResponse(statusCode, response),
   (errorResponse) => handleCashForagePaymentError(errorResponse)
)

This response object is simply a Payment object from Forage's Payments API. The most important field is the status field which indicates whether the payment attempt succeeded or failed.