HandCash Payment Requests API - Corrected Documentation
Based on real-world implementation and testing. This documentation corrects errors found in the official docs.API Base URL
Authentication Headers
IMPORTANT: Headers are case-sensitive. Use lowercase:Create Payment Request
Method:POSTURL:
https://cloud.handcash.io/v3/paymentRequests
Required Fields
| Field | Type | Description | Notes |
|---|---|---|---|
product | Object | Product information | Required |
product.name | String | Product name | Required |
product.description | String | Product description | Optional but recommended |
product.imageUrl | String | Product image URL | Optional but recommended for UX |
instrumentCurrencyCode | String | Blockchain currency | Must be “BSV” or “MNEE” (NOT USD) |
currency | String | Display/denomination currency | Use “USD”, “EUR”, “GBP”, etc. |
receivers | Array | Payment recipients | Required |
receivers[].destination | String | HandCash handle or wallet ID | Required |
receivers[].sendAmount | Number | Amount to send | Required |
expirationType | String | Expiration type | Required: “limit”, “never”, or “onPaymentCompleted” |
Common Mistakes in Official Docs
-
WRONG:
denominationCurrencyCodeCORRECT:currency -
WRONG:
instrumentCurrencyCode: "USD"CORRECT:instrumentCurrencyCode: "BSV"or"MNEE"only -
WRONG:
receivers[].currencyCodefield CORRECT: Do NOT includecurrencyCodein receivers array
Working Example
Response Format
List Payment Requests
Method:GETURL:
https://cloud.handcash.io/v3/paymentRequests
Query Parameters (Optional)
status- Filter by status (e.g., “pending”, “completed”)
Example
Response
Returns array of payment request objects initems array.
Get Single Payment Request
Method:GETURL:
https://cloud.handcash.io/v3/paymentRequests/{id}
IMPORTANT: In Next.js 16+, you must await params:
Example
Update Payment Request
Method:PUTURL:
https://cloud.handcash.io/v3/paymentRequests/{id}
Updatable Fields
product.nameproduct.descriptionproduct.imageUrlredirectUrlnotifications.webhook.webhookUrlnotifications.webhook.customParametersnotifications.emailexpirationInSecondsdecreaseRemainingUnits(only forexpirationType: "limit")
Example
Delete Payment Request
Method:DELETEURL:
https://cloud.handcash.io/v3/paymentRequests/{id}
IMPORTANT: The API returns an empty response body on success. Do NOT attempt to parse as JSON.
Example
Handling Delete Response
Common Issues & Solutions
Issue: “instrumentCurrencyCode must be one of [MNEE, BSV]”
Solution: Never use “USD” forinstrumentCurrencyCode. Only use “BSV” or “MNEE”.
Issue: “denominationCurrencyCode is not allowed”
Solution: The field is calledcurrency, not denominationCurrencyCode.
Issue: “receivers[0].currencyCode is not allowed”
Solution: Do not includecurrencyCode in the receivers array.
Issue: “Unexpected end of JSON input” on DELETE
Solution: The DELETE endpoint returns an empty body. Handle this by reading as text first:Issue: “id must be a valid MongoDB ObjectId”
Solution: In Next.js 16+, dynamic route params must be awaited:Field Mapping Guide
| Official Docs | Actually Works | Type |
|---|---|---|
denominationCurrencyCode | currency | String |
instrumentCurrencyCode: "USD" | instrumentCurrencyCode: "BSV" or "MNEE" | String |
App-Id (uppercase) | app-id (lowercase) | Header |
App-Secret (uppercase) | app-secret (lowercase) | Header |
receivers[].currencyCode | ❌ Do not include | N/A |
Complete Working Implementation
See thepayment-requests-package folder for a complete, tested implementation including:
app/api/payment-requests/route.ts- POST and GET handlersapp/api/payment-requests/[id]/route.ts- GET, PUT, DELETE handlerscomponents/payment-request-management.tsx- Full UI component