Quickstart
Accept your first payment in five steps, from a new account to a fulfilled order.
Before you start
| You need | Why |
|---|---|
| A 402pay account | It owns your wallet, your keys and every payment. |
| A server | Secret keys only ever live on a server, never in a browser or app. |
| A public HTTPS endpoint | For the webhook that tells you when a payment succeeds. |
url.- 1
Create an account
Sign up with your email and a passkey or a password, enter the code we email you, then add your business and create its wallet. It takes a few minutes. Create an account.
- 2
Create a secret key
In the dashboard, open Developers, then API keys, and create a secret key. Its secret starts with
402s_live_and is shown once, so put it in your server's environment.Shellexport PAY402_SECRET_KEY="402s_live_..."There is no test mode: every payment you create is real and moves real money, so start with small amounts. - 3
Create a payment
Create it from your server when the customer is ready to pay. The response carries a hosted checkout
url.cURLcurl -X POST "https://api.402pay.co/api/v1/payments" \ -H "Authorization: Bearer $PAY402_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "amount": "49.00", "currency": "USD", "reference": "order_1042", "description": "Pro plan, monthly", "success_url": "https://example.com/thanks" }'const response = await fetch("https://api.402pay.co/api/v1/payments", { method: "POST", headers: { Authorization: `Bearer ${process.env.PAY402_SECRET_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ amount: "49.00", currency: "USD", reference: "order_1042", description: "Pro plan, monthly", success_url: "https://example.com/thanks" }), }); const { data } = await response.json();import os import requests response = requests.post( "https://api.402pay.co/api/v1/payments", headers={ "Authorization": f"Bearer {os.environ['PAY402_SECRET_KEY']}", }, json={ "amount": "49.00", "currency": "USD", "reference": "order_1042", "description": "Pro plan, monthly", "success_url": "https://example.com/thanks" }, ) data = response.json()["data"] - 4
Send the customer to checkout
Redirect to the payment's
url. Checkout handles the coin and network, cards, short transfers and the receipt, then sends the customer to yoursuccess_url. - 5
Fulfill the order on a webhook
Add a webhook endpoint for
payment.succeeded, in the dashboard under Developers, then Webhooks, or through the API. Itsurlmust be a publichttps://address, solocalhostand private networks are refused. Save the signing secret in the response: it's shown once.cURLcurl -X POST "https://api.402pay.co/api/v1/webhooks" \ -H "Authorization: Bearer $PAY402_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/402pay", "event_types": ["payment.succeeded"], "description": "Fulfill orders" }'const response = await fetch("https://api.402pay.co/api/v1/webhooks", { method: "POST", headers: { Authorization: `Bearer ${process.env.PAY402_SECRET_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://example.com/webhooks/402pay", event_types: ["payment.succeeded"], description: "Fulfill orders" }), }); const { data } = await response.json();import os import requests response = requests.post( "https://api.402pay.co/api/v1/webhooks", headers={ "Authorization": f"Bearer {os.environ['PAY402_SECRET_KEY']}", }, json={ "url": "https://example.com/webhooks/402pay", "event_types": ["payment.succeeded"], "description": "Fulfill orders" }, ) data = response.json()["data"]When it arrives, verify the signature and fulfill the order its
referencepoints to.webhooks.jsNode.js// Fulfill once, when the payment succeeds. app.post("/webhooks/402pay", express.raw({ type: "application/json" }), async (req, res) => { if (!verifyWebhook(process.env.PAY402_WEBHOOK_SECRET, req.headers, req.body)) { return res.sendStatus(400); } res.sendStatus(200); const event = JSON.parse(req.body); // A test delivery names a made-up payment, and its data holds only that id. if (event.test) return; if (event.type === "payment.succeeded") { await orders.markPaid(event.data.reference, event.data.id); } });Each delivery is a signed HTTPS request to your endpoint. Read every attempt under Developers, then Webhooks, or withGET /webhook-deliveries.
Next steps
- Going live Everything to check before you take real payments, and after.
- Hosted checkout Everything between choosing how to pay and the receipt, on one hosted page.
- Underpayments and overpayments What happens when a customer sends too little, too much, too late or on the wrong network.
- Webhooks Signed events for every change, retried until your server answers.