---
updatedAt: 2026-05-07T18:17:26.000Z
agentTools:
  projectIndex: https://docs.joinforage.app/llms.txt
---

# Update a Payment

> ⚠️ Update Payment Requests Server-Side
>
> To keep your app secure, requests to update a `Payment` should only be generated on the server-side.

A `PATCH` request to `/payments/{payment_ref}/` updates an existing Forage `Payment`.

On success, the API responds with the updated [Payment](ref:payments) object.

The `status` property of the `Payment` determines what data can be updated. If the `status` is `processing`, `cancelled`, or `succeeded`, then only the following `Payment` fields can be modified:

- `metadata`
- `external_order_id`

During these statuses, Forage ignores attempts to update other `Payment` fields.

> 📘 Required For Server-Side Capture
>
> You need to use this endpoint if you're building an integration that [defers payment capture to the server](doc:capture-ebt-payments-server-side).


# OpenAPI definition

```json
{
  "openapi": "3.0.0",
  "x-readme": {
    "explorer-enabled": false,
    "proxy-enabled": false
  },
  "info": {
    "title": "Forage Payments API",
    "description": "The Forage Payments API is a REST API for processing Electronic Benefits Transfer (EBT) payments (SNAP and EBT Cash) in your e-commerce or in-store application.\n\nProcessing any EBT payment, or checking an EBT card's balance, requires the cardholder's PIN. Federal regulations require all PIN entry to happen through a PCI-compliant, USDA-approved interface. Forage provides that interface, so EBT PIN collection always happens through a Forage-hosted surface (Forage Checkout or a Forage SDK), never directly in your own form. Some endpoints (for example, capture and balance) are only reachable through that surface because they require PIN data in the request.\n\nEBT rarely covers an entire order: items like delivery fees and non-eligible products can't be paid with SNAP or EBT Cash. You decide how to handle the remaining balance (split tender) and any credit or debit processing alongside the EBT portion.\n\nForage offers four integration options. Pick the one that fits your platform and engineering resources:\n\n1. **Fully Hosted Checkout.** Forage processes EBT and credit/debit through a Forage-hosted Checkout UI. Lowest engineering effort, and Forage absorbs most error handling. See the [Fully Hosted Checkout guide](https://docs.joinforage.app/docs/fully-hosted).\n2. **Custom Checkout.** Forage processes EBT; you handle split tender, taxes, and credit/debit in your own checkout flow. Best when you want minimal changes to your existing UX. See the [Custom Checkout guide](https://docs.joinforage.app/docs/custom).\n3. **Online SDKs.** Client-side SDKs for [web](https://docs.joinforage.app/docs/forage-js), [iOS](https://docs.joinforage.app/docs/ios), and [Android](https://docs.joinforage.app/docs/android) that collect EBT PINs in your app while keeping you out of PCI scope.\n4. **POS Terminal SDK.** Accept in-person EBT payments on an Android POS device. See the [POS Terminal guide](https://docs.joinforage.app/docs/forage-terminal-android).\n\nAs a general principle, any data created by your requests, or by your customers on a Forage-hosted surface, is retrievable through GET requests to the appropriate resource.\n\nHave more questions? Use our [contact form](https://www.joinforage.com/get-in-touch) to reach our sales and engineering support teams.\n",
    "contact": {
      "name": "API Support",
      "email": "engineering@joinforage.com"
    },
    "version": "2025-08-04"
  },
  "externalDocs": {
    "description": "Forage documentation",
    "url": "https://docs.joinforage.app/"
  },
  "servers": [
    {
      "url": "https://{environment}.joinforage.app",
      "variables": {
        "environment": {
          "default": "api.sandbox",
          "enum": [
            "api",
            "api.sandbox"
          ]
        }
      }
    }
  ],
  "security": [],
  "paths": {
    "/api/payments/{payment_ref}/": {
      "parameters": [
        {
          "name": "payment_ref",
          "in": "path",
          "description": "A unique reference hash for the Forage Payment object, returned when the [Payment was created](https://docs.joinforage.app/reference/create-a-payment).",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "parameters": [
          {
            "$ref": "#/components/parameters/AuthenticationBearerTokenHeader"
          },
          {
            "$ref": "#/components/parameters/MerchantAccountHeader"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKeyHeader"
          }
        ],
        "tags": [
          "Payments"
        ],
        "summary": "Update a Payment",
        "x-readme": {
          "code-samples": [
            {
              "language": "curl",
              "code": "curl --request PATCH \\\n    --url https://api.sandbox.joinforage.app/api/payments/cc3175bfea/ \\\n    --header 'Authorization: Bearer <api_key>' \\\n    --header 'Merchant-Account: <merchant-id>' \\\n    --header 'Idempotency-Key: <idempotency-key>' \\\n    --header 'accept: application/json'\n"
            }
          ]
        },
        "description": "> ⚠️ Update Payment Requests Server-Side\n>\n> To keep your app secure, requests to update a `Payment` should only be generated on the server-side.\n\nA `PATCH` request to `/payments/{payment_ref}/` updates an existing Forage `Payment`.\n\nOn success, the API responds with the updated [Payment](https://docs.joinforage.app/reference/payments) object.\n\nThe `status` property of the `Payment` determines what data can be updated. If the `status` is `processing`, `cancelled`, or `succeeded`, then only the following `Payment` fields can be modified:\n\n- `metadata`\n- `external_order_id`\n\nDuring these statuses, Forage ignores attempts to update other `Payment` fields.\n\n> 📘 Required For Server-Side Capture\n>\n> You need to use this endpoint if you're building an integration that [defers payment capture to the server](https://docs.joinforage.app/docs/capture-ebt-payments-server-side).\n",
        "operationId": "Update a payment",
        "security": [
          {
            "OAuth2": [
              "internal",
              "pinpad_only"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/Payment"
        },
        "responses": {
          "200": {
            "description": "__OK__ - Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "amount_mismatch": {
                    "summary": "Amount Mismatch",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "amount_mismatch",
                          "message": "Payment amount needs to equal to products amount. Payment amount: {payment_amount}, products amount: {products_amount}.",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "cannot_parse_request_body": {
                    "summary": "Cannot Parse Request Body",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "cannot_parse_request_body",
                          "message": "Parsing payment_method field failed with message: Object with ref={payment_method_ref} does not exist.",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "card_not_reusable": {
                    "summary": "Card Not Reusable",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "card_not_reusable",
                          "message": "Payment method {payment_method_ref} is not reusable",
                          "source": {
                            "resource": "Payment_Methods",
                            "ref": "{payment_method_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "different_ebt_card": {
                    "summary": "Different EBT Card",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "different_ebt_card",
                          "message": "Order {order_ref} already has EBT Payment {payment_ref} with payment_method {payment_method_ref}. Your request included payment_method {payment_method_ref}. You must use the same EBT payment_method for all EBT Payments on an Order",
                          "source": {
                            "resource": "Payment_Methods",
                            "ref": "{payment_method_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "duplicate_funding_type": {
                    "summary": "Duplicate Funding Type",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "duplicate_funding_type",
                          "message": "Order {order_ref} already has payment {payment_ref} with funding_type {funding_type}. Please modify the existing payment object instead of adding new payments with the same funding_type",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "inconsistent_funding_and_payment_method": {
                    "summary": "Inconsistent Funding and Payment Method",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "inconsistent_funding_and_payment_method",
                          "message": "Payment was posted with a funding_type of {funding_type}, but the payment_method is {card_type} card.",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "invalid_input_data": {
                    "summary": "Invalid Input Data",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "invalid_input_data",
                          "message": "Query parameter missing or incomplete.",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  },
                  "invalid_merchant_account": {
                    "summary": "Invalid Merchant Account",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "invalid_merchant_account",
                          "message": "Merchant account Merchant ID not valid.",
                          "source": {
                            "resource": "Merchants"
                          }
                        }
                      ]
                    }
                  },
                  "missing_idempotency_key": {
                    "summary": "Missing Idempotency Key",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "missing_idempotency_key",
                          "message": "You must include a value for the IDEMPOTENCY-KEY header in your requests to this endpoint.",
                          "source": {
                            "resource": "Idempotency_Key"
                          }
                        }
                      ]
                    }
                  },
                  "missing_merchant_account": {
                    "summary": "Missing Merchant Account",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "missing_merchant_account",
                          "message": "No merchant account was provided.",
                          "source": {
                            "resource": "Merchants"
                          }
                        }
                      ]
                    }
                  },
                  "unknown_fields_error": {
                    "summary": "Unknown Fields",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "unknown_fields_error",
                          "message": "Unknown field(s) provided: {unknown_fields}",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "invalid_token": {
                    "summary": "Invalid Token",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "invalid_token",
                          "message": "Incorrect authentication credentials.",
                          "source": {
                            "resource": "OAuth_Access_Tokens"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "invalid_field_update_error": {
                    "summary": "Immutable Fields",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "invalid_field_update_error",
                          "message": "Immutable fields {invalid_update_fields} cannot be updated",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "Resource Not Found",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "resource_not_found",
                          "message": "Payment with {payment_ref} does not exist.",
                          "source": {
                            "resource": "Payments",
                            "ref": "{payment_ref}"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "cannot_change_request": {
                    "summary": "Cannot Change Request",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "cannot_change_request",
                          "message": "Two requests were submitted with the same idempotency key, but slightly different request bodies. Please use a new idempotency key if you intended to change the request body",
                          "source": {
                            "resource": "Idempotency_Key"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "423": {
            "$ref": "#/components/responses/Error423"
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "too_many_requests": {
                    "summary": "Too Many Requests",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "too_many_requests",
                          "message": "Request was throttled, please try again later.",
                          "source": {
                            "resource": "Payments"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "unknown_server_error": {
                    "summary": "Unknown Server Error",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "unknown_server_error",
                          "message": "Unknown exception from EBT network",
                          "source": {
                            "resource": "Unknown"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponseObject"
                },
                "examples": {
                  "ebt_processor_timeout": {
                    "summary": "EBT processor timeout",
                    "value": {
                      "path": "/api/payments/{payment_ref}/",
                      "errors": [
                        {
                          "code": "ebt_processor_timeout",
                          "message": "Unable to contact EBT processor, please try again shortly.",
                          "source": {
                            "resource": "Payments",
                            "ref": ""
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorsArray": {
        "type": "array",
        "description": "An array with information about the error.",
        "items": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string",
              "description": "A short string that represents the error."
            },
            "message": {
              "type": "string",
              "description": "A developer-facing message with more details about the error, not to be displayed to customers."
            },
            "source": {
              "type": "object",
              "properties": {
                "resource": {
                  "type": "string",
                  "description": "The type of the Forage resource involved in the error."
                },
                "ref": {
                  "type": "string",
                  "description": "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": {
              "type": "object",
              "description": "Additional details about the error, if applicable."
            }
          }
        },
        "example": []
      },
      "ErrorResponseObject": {
        "type": "object",
        "description": "An object that includes details about the error.",
        "properties": {
          "path": {
            "type": "string",
            "description": "The requested endpoint."
          },
          "errors": {
            "$ref": "#/components/schemas/ErrorsArray"
          }
        }
      },
      "PaymentRequest": {
        "type": "object",
        "description": "This object represents a single payment. It is associated with a single payment method.",
        "properties": {
          "amount": {
            "type": "string",
            "format": "decimal",
            "description": "A positive decimal number that represents how much to charge the [`PaymentMethod`](https://docs.joinforage.app/reference/payment-methods) in USD. Precision is supported to the penny. 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."
          },
          "funding_type": {
            "type": "string",
            "description": "The payment instrument type. Use this field to differentiate between a SNAP (`ebt_snap`) and an EBT Cash (`ebt_cash`) charge on the same EBT Card. If you need to charge both funding types, then create a `Payment` for each charge. Use `credit_payfac` for all charges to HSA/FSA cards. `credit_tpp` is the funding type assigned to non-EBT payment objects created via a Fully Hosted Checkout integration.",
            "enum": [
              "ebt_snap",
              "ebt_cash",
              "credit_tpp",
              "credit_payfac",
              "benefit",
              "wic"
            ]
          },
          "payment_method": {
            "type": "string",
            "description": "The unique reference hash for the existing Forage [`PaymentMethod`](https://docs.joinforage.app/reference/payment-methods) that is to be charged in this transaction.\n\n⚠️ **Exception**: POS integrations do not need to provide a `payment_method` when creating a payment.\n"
          },
          "delivery_address": {
            "$ref": "#/components/schemas/DeliveryAddressData"
          },
          "is_delivery": {
            "type": "boolean",
            "description": "⚠️ **Exception**: If the purchase is made in-store via a POS Terminal, then a `is_delivery` is not required when creating a `Payment`.\n\nWhether the order is for delivery or pickup. This information is required per FNS regulations. Defaults to `false` if not provided.\n"
          },
          "description": {
            "type": "string",
            "description": "A description of the payment."
          },
          "metadata": {
            "$ref": "#/components/schemas/MetadataObject"
          },
          "platform_fee": {
            "type": "string",
            "format": "decimal",
            "description": "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": {
            "type": "string",
            "format": "decimal",
            "description": "The fixed amount in USD that a platform takes from EBT Cash payments prior to splitting by the `platform_fee`. Precision is supported to the penny."
          },
          "merchant_fixed_settlement": {
            "type": "string",
            "format": "decimal",
            "description": "The fixed amount in USD that should be restored to the merchant from EBT Cash payments prior to splitting by the `platform_fee`. Precision is supported to the penny."
          },
          "tpp_lookup_id": {
            "type": "string",
            "description": "An identifier for the credit/debit TPP.\n\nFor Stripe integrations, the client secret for a Stripe `PaymentIntent`.\n",
            "example": "pi_1DpdZq2eZvKYlo2CAYyzTr8j_secret_lxr4crBJP4txbrg7sqit0XQQO"
          },
          "customer_id": {
            "$ref": "#/components/schemas/CustomerIDField"
          },
          "external_order_id": {
            "$ref": "#/components/schemas/ExternalOrderIDField"
          },
          "merchant_destination_account": {
            "type": "string",
            "description": "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.\n\nDefaults to the hash for the default merchant bank account if not provided.\n"
          },
          "pos_terminal": {
            "type": "object",
            "description": "**⚠️  This param is only supported for POS Terminal integrations. Do not use this param for online transactions.**\n\nAn object that details information about the POS Terminal that processes the payment.\n",
            "properties": {
              "provider_terminal_id": {
                "type": "string",
                "description": "A unique string that identifies the POS Terminal."
              }
            }
          },
          "external_location_id": {
            "$ref": "#/components/schemas/ExternalLocationIDField"
          }
        },
        "required": [
          "funding_type"
        ]
      },
      "PaymentResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PaymentRequest"
          },
          {
            "type": "object",
            "properties": {
              "ref": {
                "type": "string",
                "description": "A unique reference hash for the Forage `Payment` object.\n\n_Note:_ `receipt.ref_number` equals `ref`.\n\nYou need to pass this value to the front-end SDK method that captures the payment.\n"
              },
              "merchant": {
                "type": "string",
                "description": "A string that represents a unique merchant ID that Forage provides during onboarding."
              },
              "status": {
                "type": "string",
                "description": "The status of the `Payment`. One of:\n\n- `canceled`: The `Payment`object can't be used.\n- `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.\n- `processing`: The outcome of the `Payment` is pending.\n- `requires_confirmation`: The `Payment` hasn't been submitted for processing.\n- `succeeded`: The `Payment` has been successfully processed and will be included in settlement. It can't be changed.\n- `authorized`: The `Payment` has been authorized, but not yet captured. Only applicable to HSA payments.\n",
                "enum": [
                  "requires_confirmation",
                  "processing",
                  "canceled",
                  "succeeded",
                  "failed",
                  "authorized"
                ]
              },
              "created": {
                "type": "string",
                "format": "date-time",
                "description": "A UTC timestamp of when the `Payment` was created, represented as an [ISO 8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string."
              },
              "updated": {
                "type": "string",
                "format": "date-time",
                "description": "A UTC timestamp of that indicates when the `Payment` was last modified, represented as an [ISO 8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string."
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "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.\n\nIf the `status` of the `Payment` is `succeeded` or `canceled`, then the `expires_at` value is `null`.\n"
              },
              "success_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "A UTC timestamp of when the `Payment` was successfully processed, represented as an [ISO 8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string. This value is `null` until the Payment enters the `succeeded` or `partial_capture` states."
              },
              "refunds": {
                "type": "array",
                "description": "References to the `Refund`s attached to this payment. The format depends on the `with_refunds` query parameter:\n\n- **Default behavior** (when `with_refunds` is `false` or omitted): Array of refund reference strings\n- **Expanded behavior** (when `with_refunds=true`): Array of full `Refund` objects with complete refund details\n",
                "items": {
                  "type": "string",
                  "description": "Refund reference string"
                }
              },
              "receipt": {
                "type": "object",
                "nullable": true,
                "description": "Most of the information that you're required to display to the customer, according to FNS regulations.\n\nThis field is `null` if the data that populates the receipt is not yet available.\n\nThe total amount paid by the customer is `snap_amount` + `ebt_cash_amount` + `other_amount`. This amount will be settled with the merchant after applying Forage's fees.\n"
              },
              "last_processing_error": {
                "type": "object",
                "nullable": true,
                "description": "The `code` and `message` values corresponding to the most recent [Payments API error](https://docs.joinforage.app/reference/errors#payments-api-errors). Always `null` when the `Payment` is created."
              },
              "previous_errors": {
                "$ref": "#/components/schemas/ErrorsArray"
              },
              "address_postal_code_check": {
                "type": "string",
                "nullable": true,
                "description": "The result of any check done on the delivery address zip code. One of:\n- `pass`: The provided information is correct and matches the data on file with the card issuer.\n- `fail`: The provided information is incorrect and does not match the data on file.\n- `unavailable`: The card issuer will not perform the check.\n- `unchecked`: The information was provided but has not yet been checked by the card issuer.\n",
                "enum": [
                  "pass",
                  "fail",
                  "unavailable",
                  "unchecked"
                ],
                "example": "pass"
              },
              "cvc_check": {
                "type": "string",
                "nullable": true,
                "description": "The result of any check done on the CVC. One of:\n- `pass`: The provided information is correct and matches the data on file with the card issuer.\n- `fail`: The provided information is incorrect and does not match the data on file.\n- `unavailable`: The card issuer will not perform the check.\n- `unchecked`: The information was provided but has not yet been checked by the card issuer.\n",
                "enum": [
                  "pass",
                  "fail",
                  "unavailable",
                  "unchecked"
                ],
                "example": "pass"
              },
              "delivery_address": {
                "type": "object",
                "nullable": true,
                "description": "The delivery or pickup address for the order, passed to the EBT network. Returns an address object with `line1`, `line2`, `city`, `state`, `zipcode`, and `country`. Null when no delivery address is set."
              },
              "is_delivery": {
                "type": "boolean",
                "nullable": true,
                "description": "Whether the order is for delivery or pickup. Null when not specified."
              }
            },
            "required": [
              "ref",
              "status",
              "created",
              "updated"
            ]
          }
        ],
        "example": {
          "amount": "25.99",
          "funding_type": "ebt_snap",
          "payment_method": "ac47392bb1",
          "delivery_address": {
            "city": "San Francisco",
            "country": "US",
            "line1": "1856 Market St.",
            "zipcode": "94106",
            "state": "CA"
          },
          "is_delivery": true,
          "description": "An EBT Payment",
          "metadata": {},
          "platform_fee": "0.05",
          "platform_fixed_settlement": "5.11",
          "merchant_fixed_settlement": "5.95",
          "customer_id": "cus_1234567890",
          "external_order_id": "1f2ee410-5b47-4130-aec2-40f5eb2108f5",
          "merchant_destination_account": "1bdefaa456",
          "pos_terminal": {
            "provider_terminal_id": "tbd123"
          },
          "external_location_id": "6e3b2ff7-51c8-4c64-befa-2eac90f7c3e9",
          "ref": "cc3175bfea",
          "merchant": "9000055",
          "status": "requires_confirmation",
          "created": "2021-06-16T00:11:50.000000Z",
          "updated": "2021-06-16T00:11:50.000000Z",
          "expires_at": "2021-06-16T00:41:50.000000Z",
          "success_date": "2021-06-16T00:11:50.000000Z",
          "refunds": [
            "ac47392bb1"
          ],
          "receipt": {
            "ref_number": "cc3175bfea",
            "is_voided": true,
            "snap_amount": "25.99",
            "ebt_cash_amount": "10.99",
            "other_amount": "5.99",
            "sales_tax_applied": "5.16",
            "balance": {
              "snap": "72.94",
              "non_snap": "32.16",
              "updated": "2021-06-16T00:11:50.000000Z"
            },
            "last_4": "3456",
            "message": "Approved",
            "transaction_type": "Payment",
            "created": "2021-06-16T00:11:50.000000Z"
          },
          "last_processing_error": null,
          "previous_errors": []
        }
      },
      "DeliveryAddressData": {
        "type": "object",
        "required": [
          "line1",
          "zipcode"
        ],
        "description": "⚠️ **Exception**: If the purchase is made in-store via a POS Terminal, then a `delivery_address` is not required when creating a `Payment`.\n\nThe 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.\n",
        "properties": {
          "city": {
            "type": "string",
            "description": "The name of the city."
          },
          "country": {
            "type": "string",
            "description": "Either `us` or `US`. Defaults to `US` if not provided."
          },
          "line1": {
            "type": "string",
            "description": "The first line of the street address."
          },
          "line2": {
            "type": "string",
            "nullable": true,
            "description": "The second line of the street address."
          },
          "zipcode": {
            "type": "string",
            "description": "The zip or postal code."
          },
          "state": {
            "type": "string",
            "description": "The two-letter abbreviation, can be upper or lowercase, for the US state."
          }
        }
      },
      "CustomerIDField": {
        "type": "string",
        "maxLength": 64,
        "description": "**⚠️ If you’re integrating Forage with a POS Terminal, then do not use this param. It is only supported for online transactions.**\n\nA unique identifier for the end customer making the payment.\n\nForage automatically adds the `customer_id` to the Session's corresponding `Order` and `OrderPayments`.\n\nThis 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. **It is strongly recommended to pass customer_id.**\n\nIf you're providing your internal customer ID, then we recommend that you hash the value before sending it on the payload.\n\nEach customer should only have one unique `customer_id`. For example, if you create both a `PaymentMethod` and a Forage `Session` (Fully Hosted or Custom) or `Payment` (SDK) for the same customer, then the `customer_id` should be the same in both requests to ensure continuity of stored payment methods.\n"
      },
      "ExternalOrderIDField": {
        "type": "string",
        "maxLength": 64,
        "description": "A unique identifier for the order as created by the merchant or platform (not Forage).\n\nWhen 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.\n\n**You must build with Forage Version `2023-05-15` or later to use `external_order_id`.** Either pass `2023-05-15` as the `API-Version` header on a per request basis, or set the version for all requests in the Forage dashboard.\n"
      },
      "ExternalLocationIDField": {
        "type": "string",
        "description": "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.\n",
        "example": "6e3b2ff7-51c8-4c64-befa-2eac90f7c3e9"
      },
      "MetadataObject": {
        "type": "object",
        "description": "A required object containing merchant-defined key-value pairs to provide additional context for the payment.\n\nMerchants should use this field to store **reference information** relevant to the transaction (for example, order details, system identifiers, or tracking data). This helps link the payment to records within their system.\n\nPass an empty object (`{}`) if no additional information is available.\n\n> ⚠️ Personally Identifiable Information\n>\n> **Do not include personally identifiable information (PII)** such as names, emails, or payment details.\n"
      }
    },
    "requestBodies": {
      "Payment": {
        "description": "Object which represents a single charge of a given amount to one payment method",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PaymentRequest"
            }
          }
        }
      }
    },
    "responses": {
      "Error423": {
        "description": "__Locked__ - The request could not be completed because the target resource is currently locked.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponseObject"
            },
            "examples": {
              "resource_locked": {
                "summary": "Resource Locked",
                "value": {
                  "path": "/api/example_path/",
                  "errors": [
                    {
                      "code": "resource_locked",
                      "message": "Request could not be completed because the resource is currently locked. Please try again later.",
                      "source": {
                        "resource": "Idempotency_Key",
                        "ref": ""
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "parameters": {
      "AuthenticationBearerTokenHeader": {
        "name": "Authorization",
        "in": "header",
        "description": "An OAuth 2.0 [authentication token](https://docs.joinforage.app/docs/authentication#authentication-tokens) that validates the request. Send a `POST` to the [`/o/token/`](https://docs.joinforage.app/reference/create-authentication-token) endpoint to generate an authentication token. Pass the token in this header after the word `Bearer` and a whitespace, for example `Bearer <api_key>`.",
        "schema": {
          "type": "string"
        },
        "required": true
      },
      "MerchantAccountHeader": {
        "name": "Merchant-Account",
        "in": "header",
        "description": "A unique merchant ID that Forage provides during onboarding, as in `123ab45c67`. The Merchant ID can be found in the Forage [sandbox](https://dashboard.sandbox.joinforage.app/login/) or [production](https://dashboard.joinforage.app/login/) dashboard.",
        "schema": {
          "type": "string"
        },
        "required": true
      },
      "IdempotencyKeyHeader": {
        "name": "Idempotency-Key",
        "in": "header",
        "description": "An alphanumeric key that clients can use to identify repeated requests that are dropped in transit. Generate a distinct key for every unique request and only re-use keys for retries.",
        "schema": {
          "type": "string"
        },
        "required": true
      }
    },
    "securitySchemes": {
      "OAuth2": {
        "type": "oauth2",
        "description": "Pass the access token in the 'Authorization' header with the format \"Bearer ${token}\", i.e. the word \"Bearer\" and your access token from the /o/token/ API, separated by whitespace.\n",
        "flows": {
          "password": {
            "tokenUrl": "/o/token/",
            "scopes": {
              "hosted_checkout": "Scope for tokens used by merchant applications which allow Forage to manage split tender processing (i.e. EBT + Credit/Debit).\n",
              "pinpad_only": "Scope for tokens used by merchant applications which manage their own split tender (i.e. Forage Checkout is used only for EBT processing).\n"
            }
          },
          "clientCredentials": {
            "tokenUrl": "/o/token/",
            "scopes": {
              "internal": "Scope for tokens used by Forage internal applications.\n",
              "pin-protected": "Scope for tokens which can access secure storage.\n",
              "disbursement": "Scope for tokens which can disburse money to merchants.\n"
            }
          }
        }
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Pass the access token in the 'Authorization' header with the format \"Bearer ${token}\", i.e. the word \"Bearer\" and your JWT bearer token from the /api/session_token/ end-point, separated by whitespace.\n"
      }
    }
  }
}
```

# Sibling pages

* [Create a Payment](https://docs.joinforage.app/reference/create-a-payment.md)
* [Retrieve all Payments for a merchant order ID](https://docs.joinforage.app/reference/retrieve-all-payments-for-merchant-order-id.md)
* [Retrieve a Payment](https://docs.joinforage.app/reference/get-payment-details.md)
* [Deferred Capture](https://docs.joinforage.app/reference/deferred-capture-1.md)
* [Testing](https://docs.joinforage.app/reference/testing-endpoints.md)
* [Cancel or Void a Payment](https://docs.joinforage.app/reference/cancel-a-payment.md)
* [Authorize a Payment](https://docs.joinforage.app/reference/authorize-a-payment.md)
* [Void a Payment](https://docs.joinforage.app/reference/void-a-payment-custom-checkout.md)