Payment Links

Get paid with a shareable link — no checkout integration required

A payment link is a hosted, shareable way to collect a payment without building a checkout. You create the link with a single API call, send the customer the URL (by email, SMS, or chat), and they pay on a branded page. Funds settle into the same account as your other card payments.

Common use cases

  • Collect a one-off payment when you don't have a storefront or app checkout
  • Send a "pay now" request by email or text, with the amount already locked
  • Take payment over the phone by texting a link instead of reading card numbers aloud
  • Re-bill a returning customer using the card saved from their first payment
ℹ️

Payment links accept card payments by default. If the merchant has the ACH.com product active, the hosted payment page also shows an ACH option. For a fully embedded card + ACH checkout, use the Priority Checkout Widget.


Create your first payment link

The fastest way to see this work: create a link, then share the hosted URL you build from the returned id. Send the minimal request below — the full field list is in the Request reference.

POST /checkout/v3/device

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "enabled": true,
  "onSuccessUrl": "https://your-app.example.com/paid",
  "onFailureUrl": "https://your-app.example.com/failed"
}

You'll get back the link resource, including its id:

{
  "id": "faf264a2-bedc-494e-97e8-96ec87020a14",
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "deviceTypeName": "Payment Link",
  "enabled": true,
  "merchantId": 1000156763,
  "onSuccessUrl": "https://your-app.example.com/paid",
  "onFailureUrl": "https://your-app.example.com/failed",
  "transactionCount": 0,
  "transactionTotalAmount": "0",
  "customerCount": 0
}

Build the hosted payment-page URL from the returned id and share it with your customer:

https://<pce-hosted-pay-page>/d/{id}/v3

Keep the id to retrieve, disable, or delete the link later.

The endpoint is POST /checkout/v3/device. deviceType must be Link2Pay for a payment link — the endpoint accepts other device types for other products, but only Link2Pay applies here.


Scenarios

Every payment link is created with POST /checkout/v3/device. What changes per scenario is the fields you set on the link.

Before you begin (all scenarios)

  • You have your merchantId and PCE API credentials.
  • Your onSuccessUrl / onFailureUrl endpoints are reachable to receive the customer after payment.

Scenario 1: Collect a fixed amount

(Lock the amount so the customer can't change it)

Use this to bill a specific amount — an invoice, a quote, a deposit. Create the link with POST /checkout/v3/device, setting MinPaymentAmount and MaxPaymentAmount to the same value to lock the field.

Request

POST /checkout/v3/device

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "enabled": true,
  "MinPaymentAmount": 250,
  "MaxPaymentAmount": 250,
  "onSuccessUrl": "https://your-app.example.com/paid",
  "onFailureUrl": "https://your-app.example.com/failed"
}

To let the customer choose the amount instead (for example, a donation or an open balance), omit both MinPaymentAmount and MaxPaymentAmount.

Scenario 2: Show an invoice-number field on the payment page

(Match the payment back to your system)

Create the link with POST /checkout/v3/device and set InvoiceFieldEnabled to true. The payment page then shows an invoice-number field for the customer to complete.

Request

POST /checkout/v3/device

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "enabled": true,
  "MinPaymentAmount": 250,
  "MaxPaymentAmount": 250,
  "InvoiceFieldEnabled": true,
  "onSuccessUrl": "https://your-app.example.com/paid",
  "onFailureUrl": "https://your-app.example.com/failed"
}

Scenario 3: Make a link one-time-use

(Prevent a second payment on the same link)

A payment link stays payable until you turn it off — the same link can be paid more than once. To enforce a single payment, disable or delete the link once you've confirmed the first payment.

Disable it (keeps the record, stops new payments) with PUT /checkout/v3/device — resend the link with enabled set to false:

PUT /checkout/v3/device?id=faf264a2-bedc-494e-97e8-96ec87020a14

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "enabled": false,
  "MinPaymentAmount": 250,
  "MaxPaymentAmount": 250
}

Or delete it entirely with DELETE /checkout/v3/device:

DELETE /checkout/v3/device?id=faf264a2-bedc-494e-97e8-96ec87020a14

Scenario 4: Re-bill a returning customer

(Charge a card the customer already used on a link)

When a customer pays through a link, PCE stores their card and creates a customer record. Reuse that saved token for later charges — no new link required.

  1. Get the payment and its customer with GET /checkout/v3/payment/{id} using includeCustomer=true, and read the customerId.
  2. List the customer's saved cards and take the token.
  3. Charge the saved card with POST /checkout/v3/payment:
POST /checkout/v3/payment

{
  "paymentType": "Sale",
  "merchantId": "1000156763",
  "tenderType": "Card",
  "amount": 250,
  "source": "API",
  "customer": { "id": "10000001463608" },
  "cardAccount": { "token": "TNKY0O723SQMX3XWRV1JULV9WKP1HPSH" }
}

For repeating schedules, see Invoicing & Recurring Billing.

Scenario 5: Set the link to expire

(Stop the link from being paid after a deadline)

Set UtcDateExpiration to a UTC timestamp when creating or updating the link. After that time, the hosted page no longer accepts payment. You can set it on create with POST /checkout/v3/device or add or change it later with PUT /checkout/v3/device.

Request

POST /checkout/v3/device

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "enabled": true,
  "MinPaymentAmount": 250,
  "MaxPaymentAmount": 250,
  "UtcDateExpiration": "2026-09-05T04:00:00Z",
  "onSuccessUrl": "https://your-app.example.com/paid",
  "onFailureUrl": "https://your-app.example.com/failed"
}

Omit UtcDateExpiration if the link should never expire.


Track and reconcile

Your onSuccessUrl and onFailureUrl receive the customer after payment, with transaction details (including transId and the invoice number) as query parameters.

As a fallback — for example, if your callback doesn't fire — review your payments with GET /checkout/v3/payment and match the transId your callback would have carried:

GET /checkout/v3/payment?merchantId=1000156763&limit=50&offset=0

Request reference

The fields for POST /checkout/v3/device. The scenarios above use subsets of these.

ParameterRequiredDescription
deviceTypeMust be Link2Pay to create a payment link. The endpoint accepts other device types for other products, but only Link2Pay applies here.
merchantIdThe merchant's unique identifier that receives the payment.
nameYour internal label for the link (shown in reporting).
enabledtrue makes the link payable; false turns it off.
descriptionFree-text description of the link.
MinPaymentAmountMinimum amount the customer can pay. Set equal to MaxPaymentAmount to lock the amount. Omit both to let the customer choose.
MaxPaymentAmountMaximum amount the customer can pay.
UtcDateExpirationUTC timestamp when the link expires, for example 2026-09-05T04:00:00Z. Settable on create and update. Omit for no expiry.
InvoiceFieldEnabledtrue shows an invoice-number field on the payment page.
onSuccessUrlURL the customer returns to after a successful payment.
onFailureUrlURL the customer returns to after a failed payment.

Key response fields: id (use it to retrieve, update, or delete the link, and to build the hosted URL https://<pce-hosted-pay-page>/d/{id}/v3), deviceTypeName (Payment Link), and transactionCount / transactionTotalAmount (activity on the link).


Manage payment links

ActionEndpoint
List all linksGET /checkout/v3/device?merchantId={id}&deviceType=Link2Pay&limit=100&offset=0
Get one linkGET /checkout/v3/device?id={id}
Disable / update a linkPUT /checkout/v3/device?id={id} (resend the body with your changes)
Delete a linkDELETE /checkout/v3/device?id={id}

Custom fields

Custom fields add extra inputs to the payment page — for example a PO number or a membership ID. You define them once for the merchant with fieldSourceType set to paymentLink; they then apply to the merchant's payment links.

Create a custom field

POST /checkout/v3/paymentproperty?merchantId=1000156763

{
  "fieldName": "poNumber",
  "fieldDataType": "String",
  "fieldSourceType": "paymentLink",
  "isSystem": false,
  "isRequired": false,
  "isDeleted": false,
  "options": [],
  "name": "poNumber",
  "required": false
}

Create via POST /checkout/v3/paymentproperty. Set fieldSourceType to paymentLink; fieldDataType accepts the same types as the UI (for example String, Integer, List). List the fields afterward to get the new field's id.

List custom fields

GET /checkout/v3/paymentproperty?merchantId=1000156763

List via GET /checkout/v3/paymentproperty. Each record returns its id, name, fieldDataType, and required flag. To return only specific fields, pass their IDs in the optional properties query parameter — a list of custom-field IDs, for example ?merchantId=1000156763&properties=2018,2019.

Retrieve one custom field

GET /checkout/v3/paymentproperty?id=2019&merchantId=1000156763

Retrieve via GET /checkout/v3/paymentproperty. The id (2019 here) is an example — use an ID returned by the list call.

Attach custom fields to a payment link

Enable custom fields on a link by sending a properties array of custom-field IDs when you create or update the link (POST or PUT /checkout/v3/device). The array is the full set of fields to show on that link.

PUT /checkout/v3/device?id=faf264a2-bedc-494e-97e8-96ec87020a14

{
  "name": "Invoice 1042",
  "deviceType": "Link2Pay",
  "merchantId": 1000156763,
  "properties": [2060, 2059, 2063]
}
  • Send an empty properties array to disable all custom fields on the link.
  • Omit the properties key to leave the link's custom fields unchanged.

Retrieve the link to confirm — the enabled fields appear in its properties array as custom-field IDs.

How submitted values come back

When a customer completes the fields and pays, the values are returned on the payment record, in a properties array. Each entry carries the field name, fieldDataType, required flag, and the customer's response:

"properties": [
  {
    "name": "PO Number",
    "fieldDataType": "0",
    "required": true,
    "response": "PO-4471",
    "utcDateCreated": "0001-01-01T00:00:00",
    "utcDateModified": "0001-01-01T00:00:00"
  }
]

Read the payment with GET /checkout/v3/payment/{id} to retrieve these values.


Brand the payment page

Control the look of the hosted payment page — fonts, colors, and logo — with the payment link settings. These apply to every payment link for the merchant.

Read the current settings

GET /checkout/v3/paymentlinksetting?merchantId=1000156763

Update the settings

POST /checkout/v3/paymentlinksetting?merchantId=1000156763

{
  "fontFamily": "Arial",
  "fontSize": 10,
  "fontColor": "#a72626",
  "backgroundColor": "#cb1515",
  "logo": "",
  "logoWidth": 0,
  "logoHeight": 0,
  "logoSize": 0
}

Read via GET /checkout/v3/paymentlinksetting; save via POST /checkout/v3/paymentlinksetting.

FieldTypeDescription
fontFamilystringFont family for text on the payment page.
fontSizeintegerFont size for text on the payment page.
fontColorstringText color (hex).
backgroundColorstringPage background color (hex).
logostringMerchant logo for the page.
logoWidthintegerLogo width.
logoHeightintegerLogo height.
logoSizeintegerOverall logo size.

Next steps

See also



Did this page help you?
.readme-logo { display: none !important; }