U.CASH Pay custom payment integration for commercetools. Crypto + cards, non-custodial.
This package adds U.CASH Pay as a custom payment method in your commercetools project. Shoppers pay with crypto (Bitcoin, EVM coins, and more) or with cards via your own Stripe, and the funds land in your own wallets. U.CASH Pay never holds customer funds: it is non-custodial.
The integration ships as:
- A TypeScript library (
src/ucash.ts,src/commercetools.ts) that maps a commercetools cart onto a U.CASH Pay checkout. - A standalone HTTP service (
src/server.ts) that implements the commercetools API Extension contract and exposes convenience JSON routes.
There are two ways to start a payment, both supported here:
- Client-side (hosted pay link). Build a URL from the publishable store Cloud Token and load it in the browser. No server secret required.
- Server-side (tracked checkout). Create a payment record on pay.u.cash
from your server. Idempotent per
external_reference.
commercetools Cart
|
| (centAmount -> decimal amount)
v
+---------------------+ embed.php (client-side, publishable)
| this integration | ---> https://pay.u.cash/embed.php?cloud=...&amount=...
+---------------------+ ajax.php (server-side, idempotent)
|
v
U.CASH Pay hosted page (crypto + Stripe cards, non-custodial)
|
v
Funds land in YOUR wallets (receive addresses + your Stripe)
commercetools represents money as centAmount (integer, smallest currency
unit). This integration converts that to a decimal amount string before calling
U.CASH Pay.
# from source (recommended for now)
git clone https://github.com/UdotCASH/commercetools-ucashpay.git
cd commercetools-ucashpay
npm install
npm run buildCopy the env template and fill in your values:
cp .env.example .env
# edit .env: set UCASH_CLOUD_TOKEN (publishable) and your commercetools clientPublish to your own registry (optional, not required to use this):
npm version patch
npm publishThe store Cloud Token is publishable, so you can build the link straight from the browser or your storefront backend:
import { buildEmbedUrlForCart } from "commercetools-ucashpay";
// cart is a commercetools Cart resource (you only need id/key + totalPrice).
const url = buildEmbedUrlForCart(cart, process.env.UCASH_CLOUD_TOKEN, {
redirect: "https://store.example/thanks",
});
// -> https://pay.u.cash/embed.php?cloud=...&amount=12.99¤cy=USD&external_reference=...Then redirect the shopper, or load it in an iframe / popup.
For reconciliation and webhooks, create the payment server-side:
import { createPaymentForCart } from "commercetools-ucashpay";
const intent = await createPaymentForCart(cart, process.env.UCASH_CLOUD_TOKEN, {
redirect: "https://store.example/thanks",
});
// intent.paymentUrl -> the hosted U.CASH Pay URL
// intent.transactionId -> the pay.u.cash transaction id
// intent.externalReference -> the stable reference used for dedupe + webhooksThe same external_reference retried within the idempotency window returns the
same checkout instead of creating a duplicate.
Run the service:
npm run build && npm start
# listening on :3000Register the extension on the Payment resource (commercetools Merchant Center or API). Point it at your deployed service:
POST https://<your-service>/ct/extension
trigger: Payment (Create, Update)
When a payment is created or updated, commercetools POSTs the resource to your service. The service:
- Reads the amount and reference off the cart/payment.
- Builds the U.CASH Pay URL.
- Optionally creates a tracked checkout (set
UCASH_CREATE_TRANSACTION=1). - Returns
UpdateActions that writeucashpay_payment_urlback onto the Payment as a custom field and log an interface interaction.
You can also call the convenience routes directly:
# client-side embed URL
curl "http://localhost:3000/embed?amount=12.50&external_reference=ORDER-1"
# server-side tracked checkout
curl -X POST http://localhost:3000/create-payment \
-H 'content-type: application/json' \
-d '{"amount":"12.50","external_reference":"ORDER-1"}'This integration talks to the public, documented endpoints of pay.u.cash. No funds pass through this service.
Client-side hosted pay link (publishable Cloud Token, browser-safe):
GET https://pay.u.cash/embed.php
cloud, amount, currency (default USD), title, external_reference, redirect
Server-side tracked checkout (idempotent per external_reference):
POST https://pay.u.cash/payment/ajax.php
function=create-transaction
amount, currency_code, cryptocurrency_code= (empty string)
external_reference, title, redirect, cloud, idempotent=1
The response is { success: true, response: [paymentUrl, transactionId, ...] },
and the payment URL is the array element that starts with http(s)://.
| Variable | Required | Description |
|---|---|---|
UCASH_CLOUD_TOKEN |
yes | Store-level Cloud Token from pay.u.cash. Publishable. |
UCASH_DEFAULT_CURRENCY |
no | Default currency code. Defaults to USD. |
UCASH_CREATE_TRANSACTION |
no | Set to 1 to also create a tracked checkout in the API Extension path. |
CTP_PROJECT_KEY |
ext | commercetools project key (API Extension auth). |
CTP_CLIENT_ID |
ext | commercetools API client id. |
CTP_CLIENT_SECRET |
ext | commercetools API client secret. |
CTP_AUTH_URL |
ext | commercetools OAuth host. |
CTP_API_URL |
ext | commercetools API host. |
PUBLIC_BASE_URL |
no | Public base URL of this service, used for the redirect target. |
PORT |
no | HTTP port. Defaults to 3000. |
"ext" = only needed when running the API Extension server with full
commercetools auth. The library helpers and the /embed + /create-payment
routes only need UCASH_CLOUD_TOKEN.
The smoke test runs locally with no network calls:
npm run build
npm run test:smokeUnit tests (Jest):
npm test- Sign up at pay.u.cash, then click the verification link in the email.
- Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
- Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
- For fiat cards, connect your own Stripe under Settings -> Payment processors.
- Non-custodial. This service holds no customer funds and no secret keys. It only stores the publishable store Cloud Token and your commercetools API client (read-only Manage Payments is sufficient).
- Refunds. Crypto refunds are initiated manually from your pay.u.cash dashboard or your own wallet; this integration creates checkouts, it does not automate on-chain refunds.
- Webhooks. Configure a webhook in your pay.u.cash store pointing at your
order-management endpoint to confirm payments. Map pay.u.cash
external_referenceback to your commercetools order key. - Precision. commercetools
centAmountis converted to a 2-decimal display amount. For high-precision crypto amounts, call the U.CASH Pay helpers directly with the raw decimal string.
MIT. See LICENSE.