Cost+Docs

Payment Links

Create reusable payment links

Payment links are reusable URLs that allow customers to pay for an order. Unlike standard orders that expire after a single failed attempt, payment links support multiple retry attempts, making them ideal for invoices, email-based payments, and scenarios where the customer may not pay immediately.

Key Features

  • Reusable: Customers can retry payment up to 25 times if previous attempts fail.
  • Long-lived: Default expiration is 30 days (configurable via expiration_period).
  • Shareable: Send the link via email, SMS, chat, or embed it on your website.

Send a POST request to /v1/paymentlinks/:

POST /v1/paymentlinks/
curl -X POST https://api.costplus.online/v1/paymentlinks/ \
  -u YOUR_API_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_order_id": "invoice-1234",
    "amount": 995,
    "currency": "EUR",
    "description": "Invoice #1234"
  }'

The response includes the payment_url to share with the customer and a unique id for tracking:

Response (201 Created)
{
  "id": "e6eecc6a-47c5-4948-bcc0-d8b73f5c55a1",
  "merchant_order_id": "invoice-1234",
  "amount": 995,
  "currency": "EUR",
  "description": "Invoice #1234",
  "expiration_period": "P30D",
  "payment_url": "https://api.costplus.online/paymentlinks/e6eecc6a.../",
  "status": "new",
  "reason": "Payment Link was created, not yet visited",
  "orders": {},
  "created": "2026-01-15T12:00:00.000000Z"
}

Save the id — you'll use it to check the payment link status later.

Required Fields

FieldDescription
merchant_order_idYour own reference ID for the payment link
amountAmount in cents (e.g., 9.95 EUR = 995)
currencyISO 4217 currency code (e.g., EUR, GBP)

Optional Fields

FieldDescription
descriptionDescription shown to the customer
expiration_periodISO 8601 duration. Default is P30D (30 days)
return_urlURL to redirect the customer after successful payment
failure_urlURL to redirect the customer on cancellation, expiry, or error
webhook_urlURL to receive status change notifications
customerCustomer details object (name, email, etc.)

If you provide both return_url and failure_url, customers are redirected to failure_url when the order status is cancelled, expired, or error. Otherwise, all redirects go to return_url.

Send a GET request to /v1/paymentlinks/{id}/ using the payment link id from the create response:

GET /v1/paymentlinks/{id}/
curl -u YOUR_API_KEY: \
  https://api.costplus.online/v1/paymentlinks/e6eecc6a-47c5-4948-bcc0-d8b73f5c55a1/

The response includes the current status and references to all orders created from the link, grouped by their status:

Response (completed example)
{
  "id": "e6eecc6a-47c5-4948-bcc0-d8b73f5c55a1",
  "merchant_order_id": "invoice-1234",
  "amount": 995,
  "currency": "EUR",
  "description": "Invoice #1234",
  "expiration_period": "P30D",
  "payment_url": "https://api.costplus.online/paymentlinks/e6eecc6a.../",
  "status": "completed",
  "reason": "Completed",
  "completed": "2026-01-15T12:05:30.123456+00:00",
  "completed_order_id": "3bb663cc-2a20-400d-8bf6-18d9695d0c66",
  "orders": {
    "error": ["0d79014c-0aaa-4fd6-87c5-c8cfa5f5ac69"],
    "completed": ["3bb663cc-2a20-400d-8bf6-18d9695d0c66"]
  }
}

In this example, the customer made one failed attempt (order 0d79014c... in error status) before succeeding (order 3bb663cc... in completed status). You can retrieve full details of any order via GET /v1/orders/{order_id}/.

StatusDescription
newThe link has been created but no payment attempt has been made.
processingA payment attempt is currently in progress.
all_unsuccessfulAll payment attempts so far have failed. The customer can still retry (up to 25 attempts).
completedPayment was successful. The link is no longer active.
expiredThe link has expired before a successful payment was made.

The all_unsuccessful status is not a final status. The customer can still attempt to pay again until either the payment succeeds, the maximum number of attempts (25) is reached, or the link expires.

Once a payment link reaches the completed or expired status, it cannot be used again. Create a new payment link if the customer needs to pay again.

Example Workflow

  1. Create a payment link via POST /v1/paymentlinks/.
  2. Share the returned payment_url with your customer (e.g., via email, SMS, or invoice).
  3. The customer opens the link and completes payment.
  4. Cost+ sends a webhook to your webhook_url when the status changes.
  5. Verify the payment link status via GET /v1/paymentlinks/{id}/.
  6. Fulfill the order once the status is completed.

On this page