Bead Developers
  • Introduction
  • Quick Start
  • Authentication
  • Payments
    • Create Payment
    • Payment Statuses
    • Payment Webhooks
    • Test Transactions - Crypto
    • Changelog
  • Entity Management
    • Onboarding
    • Merchant Management
    • Location Management
    • Terminal Management
      • Terminal Lifecycle (Concepts)
      • Create Terminal
      • Get Terminal
      • List Terminals
      • Update Terminal
      • Delete Terminal
      • Webhook Management
      • Changelog
  • Settlement
    • Batches
    • Settlement Details
  • Reporting
    • Payment History Concepts
      • Pagination and Sorting
    • Partner Payments
    • Merchant Payments
    • Terminal Payments
    • Changelog
  • Reference Guide
  • FAQs & Troubleshooting
    • Authentication FAQs
    • Payments FAQs
      • Resolving “403 Forbidden” When Creating Payments
    • Webhooks & Error Codes
    • Environment & Testing
      • How to Test Klarna Payments
      • How to Prepare for USDC Testing
Powered by GitBook
On this page
  • 1 – Understand the four-part credential set
  • 2 – Obtain a bearer token (payments scope only)
  • 3 – Create a payment
  • 4 – Common 403 causes & fixes
  • 5 – Still blocked?
  1. FAQs & Troubleshooting
  2. Payments FAQs

Resolving “403 Forbidden” When Creating Payments

Use this guide to troubleshoot 403 errors returned by POST /payments endpoints. A 403 almost always means one or more parts of the payment credential set do not match.

1 – Understand the four-part credential set

Each hosted payment page (terminal entity) is tied to exactly one credential pair and must be addressed with the matching merchant/terminal IDs:

Part
Where you get it
Notes

client_id

Provided in your boarding package

Used only to fetch a bearer token for payments

client_secret

Provided with the client_id

Keep private; rotate if compromised

merchantId

Returned in boarding response or portal

Unique to the Volt MS Merchant record

terminalId

Returned in boarding response or portal

Represents the hosted page instance

All four values form an atomic set—mixing values from different sets will result in a 403.

2 – Obtain a bearer token (payments scope only)

POST /oauth2/token
Host: api.test.devs.beadpay.io      # or api.devs.beadpay.io for production
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET

Example successful response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "payments"
}

Tokens obtained with these credentials are only for payments; they cannot be used for boarding operations such as creating webhooks, entities, or terminals.

Token-caching rule

Cache the token per credential set. When switching to a different terminal/merchant pair, request a new token—even if the previous one is still valid.

3 – Create a payment

POST /payments/crypto
Host: api.test.devs.beadpay.io
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "merchantId"   : "YOUR_MERCHANT_ID",
  "terminalId"   : "YOUR_TERMINAL_ID",
  "requestedAmount": 1.00,
  "paymentUrlType": "web",
  "reference"     : "ORDER-123"
}

4 – Common 403 causes & fixes

Cause
Check & fix

Wrong merchant or terminal ID

Verify IDs against the latest boarding email/portal.

Token generated with mismatched credentials

Ensure client_id & client_secret belong to the same terminal/merchant pair used in the payment body.

Re-using a cached token for a different terminal

Always fetch a new token when switching terminals.

Mixing sandbox and production

Sandbox IDs work only on api.test.devs.beadpay.io; production IDs work only on api.devs.beadpay.io.

Token expired

Check expires_in; refresh if older than one hour.

5 – Still blocked?

  1. Confirm the four-part set in a text file—no blanks, no extra spaces.

  2. Call GET /payments/{trackingId} with the same token to see if the token is valid at all.

  3. Contact developer support with the timestamp, trackingId (if any), and request ID from the 403 response headers.

PreviousPayments FAQsNextWebhooks & Error Codes

Last updated 8 days ago