A Payment object represents a one-time charge to an existing PaymentMethod.
PaymentUse By Integration TypePayment objects are only relevant to SDK integrations. If you’re building with the Fully Hosted or Custom Forage Checkout UI, then use the
OrderandOrderPaymentobjects.
With the Forage Payments API, you can:
- Create a Payment: POST
/payments/ - Retrieve a Payment: GET
/payments/{payment_ref}/ - Update a Payment: POST
/payments/{payment_ref}/ - Cancel a Payment: POST
/payments/{payment_ref}/cancel/ - Retrieve all Payments for a given merchant identifier: GET
/payments/
You need a ref to a Payment object to complete a transaction. All front-end SDK methods that authorize a payment require the ref as a parameter, for example:
Payment object
Payment object{
"ref": "0ddbcda871",
"merchant": "2222222",
"funding_type": "ebt_snap",
"amount": "20.00",
"description": "An EBT payment",
"metadata": {
"psp_customer_id": "cus_1234567890"
},
"payment_method": "8ef9edff51",
"customer_id": "abc123",
"delivery_address": {
"city": "San Francisco",
"country": "US",
"line1": "1856 Market St.",
"line2": null,
"state": "CA",
"zipcode": "94106"
},
"is_delivery": false,
"created": "2023-09-18T11:38:29.279185-07:00",
"updated": "2023-09-18T11:38:29.279209-07:00",
"status": "requires_confirmation",
"last_processing_error": null,
"success_date": null,
"receipt": null,
"refunds": [],
"expires_at": "2023-09-18T12:08:29.279209-07:00",
"previous_errors": [],
"requested_amount": "30.00",
"authorization_amount": "25.00",
"qualified_healthcare_total": "20.00",
"qualified_healthcare_subtotal": "20.00"
}
Initial
PaymentStatus And ReceiptWhen a
Paymentis initially created, thestatusvalue is alwaysrequires_confirmation, and thereceiptvalue is alwaysnull.
Payment Expiration Timing
If a
Paymentis not captured or canceled within 30 minutes of when it is created, then thePaymentexpires. Inspect theexpires_atfield to find a timestamp of the expiration.
Properties
| Property | Type | Description |
|---|---|---|
ref | string | A unique reference hash for the Forage Payment object.You need to pass this value to the front-end SDK method that captures the payment. |
merchant | string | A string that represents either the merchant’s FNS number, or a unique merchant ID that Forage provides during onboarding. |
funding_type | string | A string that represents the type of tender. One of: - ebt_snap- ebt_cash- credit_tpp- benefit |
amount | string | A positive decimal number representing how much to charge the PaymentMethod in USD. Precision to the penny is supported. The minimum amount that can be charged is 0.01. To differentiate between a SNAP and an EBT Cash charge on the same EBT card, use the funding_type field. If you need to charge both funding types, then create a Payment for each charge. |
description | string | A string that describes the Payment. |
metadata | object | A set of optional, merchant-defined key-value pairs that can be added to an object. For example, some merchants attach their credit card processor’s ID for the customer making the payment. If there’s no additional information that you’d like to add, then pass an empty object as the value. |
payment_method | string | The unique reference hash for the existing Forage PaymentMethod that is to be charged in this transaction. |
platform_fee | number | An optional field, for use by a platform supporting multiple merchants, that indicates the percentage cut of each payment that the platform charges as a fee. |
platform_fixed_settlement | number | The fixed amount in USD that a platform takes from EBT Cash payments prior to splitting by the platform_fee. Precision to the penny is supported. |
merchant_fixed_settlement | number | The fixed amount in USD that should be restored to the merchant from EBT Cash payments prior to splitting by the platform_fee. Precision to the penny is supported. |
tpp_lookup_id | string | An identifier for the credit/debit TPP. For Stripe integrations, the client secret for a Stripe PaymentIntent. |
customer_id | string | ⚠️ If you’re integrating Forage with a POS Terminal, then do not use this param. It is only supported for online transactions. A unique identifier for the end customer making the payment. This field helps Forage's servers more quickly identify the customer associated with the request. While customer_id is not technically required, if you omit it then requests could take longer to process.If you're providing your internal customer ID, then we recommend that you hash the value before sending it on the payload. Each customer should only have one unique customer_id. For example, if you create both a PaymentMethod and a Payment for the same customer, then the customer_id should be the same in both requests. |
external_order_id | string | A unique identifier for the order as created by the merchant or platform (not Forage). When a merchant or platform passes this order ID to Forage, it persists in each Forage transaction related to the Order. This field enables merchants to map order IDs in their system to corresponding Forage Order IDs. |
merchant_destination_account | string | A unique reference hash for the bank account that is to receive funds settlement for this payment. Use this field if you're settling funds across multiple merchant bank accounts. Reach out to your Forage account manager for details on generating a hash. Defaults to the hash for the default merchant bank account if not provided. |
pos_terminal | object | ⚠️ This param is only supported for POS Terminal integrations. Do not use this param for online transactions. An object that details information about the POS Terminal that processes the payment. Currently a provider_terminal_id key with a value that is a unique string identifying the Terminal. |
delivery_address | object | The address for delivery or pickup of the order. Per FNS regulations, this value must always be provided. If the order is for pickup, then use the merchant address. Refer to delivery address for details. |
is_delivery | boolean | Whether the order is for delivery or pickup. This information is required per FNS regulations. Defaults to false if not provided. |
created | ISO 8601 date-time string | A UTC-8 timestamp of when the Payment was created. |
updated | ISO 8601 date-time string | A UTC-8 timestamp of when the Payment was last updated. |
status | string | The status of the Payment. One of:- canceled: The Payment object can't be used.- failed: If the error is temporary, then this Payment can be resubmitted for capture without modification. Check the receipt.message field for a description of the error.- processing: The outcome of the Payment is pending.- requires_confirmation: The Payment hasn't been submitted for processing.- succeeded: The Payment has been successfully processed and will be included in settlement. It can't be changed. |
last_processing_error | object | The code and message values corresponding to the most recent Payments API error. |
success_date | ISO 8601 date-time string | A UTC-8 timestamp of when the status of the payment is succeeded. |
receipt | object | The information that you're required to display to the customer after the Payment status is succeeded, according to FNS regulations.This field is null if receipt data is not yet available for the Payment. Refer to receipt for details. |
refunds | array | An array of the unique reference hashes for any PaymentRefunds associated with this Payment. |
expires_at | ISO 8601 date-time string | A UTC timestamp of when the Payment will expire if it is not captured or canceled, set to 30 minutes from when the Payment is created. |
external_location_id | string | A unique identifier, provided by the merchant or platform (not Forage), that indicates the physical fulfillment location for the order. For example, this field could specify which location of a grocery store chain fulfilled an order. |
previous_errors | array | An array of objects that detail information about any errors triggered by the request. If the request was successful and without errors, then the field is returned as an empty array. Refer to previous_errors for details. |
requested_amount | number | The amount requested in USD. May be greater than the amount authorized after partial authorization. HSA/FSA only. |
authorization_amount | number | The amount authorized in USD. May be greater than the amount captured after undercapture. HSA/FSA only. |
qualified_healthcare_total | number | The total amount of qualified healthcare items in the order after discounts, including tax, shipping, and fees, in USD. HSA/FSA only. |
qualified_healthcare_subtotal | number | The total amount of qualified healthcare items in the order before any discounts, adjustments, taxes, or fees, in USD. HSA/FSA only. |
delivery_address
delivery_address| Property | Type | Description |
|---|---|---|
city | string | The name of the city. |
country | string | The constant string US. |
line1 | string | The first line of the street address. |
line2 | string | The second line of the street address. |
state | string | A two-letter abbreviation for the US state. |
zipcode | string | A zip or postal code. |
receipt
receipt
receiptUnavailable Until Payment SucceedsThe
receiptvalue is null when thePaymentis first created and until receipt data is available. Pass therefreturned in the response to create thePaymentin periodic GET requests to/payments/{payment_ref}/until thestatusof thePaymentissucceeded. At that point, the receipt data, including the balance, is up-to-date.
| Property | Type | Description |
|---|---|---|
ref_number | string | The unique reference hash of the Forage Payment. |
is_voided | boolean | Whether the Payment has been voided. If false, then the Payment amount has been charged as expected. In the rare case of true, the charge has been refunded. |
snap_amount | string | The USD amount charged/refunded to the SNAP balance of the EBT Card, represented as a numeric string. |
ebt_cash_amount | string | The USD amount charged/refunded to the EBT Cash balance of the EBT Card, represented as a numeric string. |
other_amount | string | The USD amount charged/refunded to any payment method that is not an EBT Card, represented as a numeric string. |
sales_tax_applied | string | The USD amount of taxes charged to the customer’s non-EBT payment instrument, represented as a numeric string. |
balance | object | Refer to balance for details. |
last_4 | string | The last four digits of the EBT Card number. |
message | string | A message from the EBT payment network that must be displayed to the customer. |
transaction_type | string | A constant string that is used to identify the transaction associated with the receipt. Always Payment in the case of payments. |
created | ISO 8601 date-time string | A UTC-8 timestamp of when the Payment was created. |
balance
balance| Property | Type | Description |
|---|---|---|
snap | string | The available SNAP balance in USD on the customer’s EBT Card, represented as a numeric string. |
non_snap | string | The available EBT Cash balance in USD on the EBT Card, represented as a numeric string. |
updated | ISO 8601 date-time string | A UTC-8 timestamp of when the funds in the account last changed. |
previous_errors
previous_errorsEach object in the previous_errors array includes the following fields:
| Property | Type | Description |
|---|---|---|
code | string | A short string that represents the error. |
message | string | A developer-facing message with more details about the error, not to be displayed to customers. |
source | object | An object that details the specific source of the Forage error, including two keys: - resource: The type of the Forage resource involved in the error.- ref: If applicable, the ten character reference hash of the Forage resource that caused the error. An empty string if no specific individual resource was involved. |
details | object | Additional details about the error, if applicable. |
Payment lifecycle
Payment lifecycleA Forage Payment enters different lifecycle stages depending on a customer’s checkout interactions. You can track a Payment's stage in the lifecycle via its status attribute.
🔄 requires_confirmation
A Payment has been created and is pending further action. It has not yet been submitted for processing, so you can still update the Payment.
From a UX perspective, Forage recommends creating a Payment after a customer inputs the SNAP and/or EBT Cash amount to apply to the cart and completes an action like clicking "Place Order".
From requires_confirmation, a Payment can move to either processing or canceled.
🔄 processing
As soon as an attempt is made to capture a Payment, its status moves to processing.
You can no longer modify the Payment.
Forage is waiting on a response from the upstream EBT benefits networks.
From a UX perspective, a capture attempt begins when an SDK customer completes an action, like clicking "Submit Payment", that calls the Forage method that captures the payment.
From processing, a Payment can move to either succeeded or failed.
✅ succeeded
The Payment has been successfully captured.
The merchant can expect to receive the funds.
The customer can expect the payment amount to be debited from their account balance.
succeeded is a terminal state. You can no longer modify the Payment or resubmit it for capture. The Payment lifecycle is complete.
❌ failed
The Payment capture failed.
You can modify the Payment, or reattempt capture.
Forage automatically moves the Payment to the canceled stage after 30 minutes.
✖️ canceled
There are many reasons to cancel a Payment. For example, a merchant might discover that they’re out of stock of a particular item, or a customer might notice a mistake in their cart.
A Payment can only be canceled if it is at the requires_confirmation or failed state.
Forage automatically cancels a Payment after 30 minutes of inactivity.
canceled is a terminal state. You can no longer modify the Payment or resubmit it for capture. The Payment lifecycle is complete.
Examples
Create a Payment
Paymentcurl --request POST \
--url https://api.sandbox.joinforage.app/api/payments/ \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Idempotency-Key: 123e4567e8' \
--header 'Merchant-Account: 9000055' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"delivery_address": {
"city": "San Francisco",
"country": "US",
"line1": "1856 Market St.",
"line2": "Unit 3",
"zipcode": "94106",
"state": "CA"
},
"customer_id": "abc123",
"is_delivery": false,
"amount": 20.00,
"funding_type": "ebt_snap",
"description": "An EBT payment"
"metadata": {},
"payment_method": "<payment-method-ref>"
}
'
Pass
customer_idIn The Request Body
customer_idhelps Forage's servers more quickly identify and associate the correct customer with the Session. Whilecustomer_idis not technically a required parameter, if you omit it then requests to create thePaymentcould take longer to process.Each customer should only have one unique
customer_id. For example, if you create both aPaymentMethodand aPaymentfor the same customer, then thecustomer_idshould be the same in both requests.
For more information, see POST /payments/ documentation.
Retrieve a Payment
Paymentcurl --request GET \
--url https://api.sandbox.joinforage.app/api/payments/{payment_ref}/ \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Merchant-Account: 9000055' \
--header 'accept: application/json' \
--header 'content-type: application/json'
For more information, see GET /payments/{payment_ref}/ documentation.
Update a Payment
Paymentcurl --request PATCH \
--url https://api.sandbox.joinforage.app/api/payments/{payment_ref}/ \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Idempotency-Key: 123e4567e8' \
--header 'Merchant-Account: 9000055' \
--header 'accept: application/json' \
--header 'content-type: application/json'\
--data '
{
"is_delivery": true,
}
'
For more information, see PATCH /payments/{payment_ref}/ documentation.
Cancel a Payment
Paymentcurl --request POST \
--url https://api.sandbox.joinforage.app/api/payments/{payment_ref}/cancel/ \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Merchant-Account: 9000055' \
--header 'accept: application/json' \
--header 'content-type: application/json'
For more information, see POST /payments/{payment_ref}/cancel/ documentation.
Retrieve all Payments for a given merchant identifier
Payments for a given merchant identifiercurl --request GET \
--url https://api.sandbox.joinforage.app/api/payments/?external_order_id={external_order_id}} \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Merchant-Account: 9000055' \
--header 'accept: application/json' \
For more information, see GET /payments/?external_order_id=<external-order-id>/ documentation.
