Payment links
A payment link is a URL anyone can pay. Create it with the API or in the dashboard, and share
it by email, chat or QR code. Each payment through it is an ordinary
payment with payment_link set.
- Create
POST /v1/payment_links - Share
urlor QR code - Payer payshosted page, your branding
- Hear it
payment.succeeded
1. Create it
Section titled “1. Create it”# A fixed price, payable once.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Research report", "amount": 2000, "currency": "gbp"}'
# A tip jar: the payer chooses between £1 and £50, and can pay repeatedly.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Tip jar", "currency": "gbp", "min_amount": 100, "max_amount": 5000, "reusable": true}'# A fixed price, payable once.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Research report", "amount": 2000, "currency": "usd"}'
# A tip jar: the payer chooses between $1 and $50, and can pay repeatedly.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Tip jar", "currency": "usd", "min_amount": 100, "max_amount": 5000, "reusable": true}'# A fixed price, payable once.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Research report", "amount": 2000, "currency": "eur"}'
# A tip jar: the payer chooses between €1 and €50, and can pay repeatedly.curl -sS https://api.tuppence.ai/v1/payment_links \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "Tip jar", "currency": "eur", "min_amount": 100, "max_amount": 5000, "reusable": true}'import { Tuppence } from "@tuppence/node";
const tuppence = new Tuppence(process.env.TUPPENCE_SECRET_KEY);
// A fixed price, payable once.const report = await tuppence.paymentLinks.create({ name: "Research report", amount: 2000, currency: "gbp" });
// A tip jar: the payer chooses between £1 and £50, and can pay repeatedly.const tips = await tuppence.paymentLinks.create({ name: "Tip jar", currency: "gbp", min_amount: 100, max_amount: 5000, reusable: true,});
console.log(report.url, report.amount_type); // … fixedconsole.log(tips.url, tips.amount_type); // … customer_choosesimport { Tuppence } from "@tuppence/node";
const tuppence = new Tuppence(process.env.TUPPENCE_SECRET_KEY);
// A fixed price, payable once.const report = await tuppence.paymentLinks.create({ name: "Research report", amount: 2000, currency: "usd" });
// A tip jar: the payer chooses between $1 and $50, and can pay repeatedly.const tips = await tuppence.paymentLinks.create({ name: "Tip jar", currency: "usd", min_amount: 100, max_amount: 5000, reusable: true,});
console.log(report.url, report.amount_type); // … fixedconsole.log(tips.url, tips.amount_type); // … customer_choosesimport { Tuppence } from "@tuppence/node";
const tuppence = new Tuppence(process.env.TUPPENCE_SECRET_KEY);
// A fixed price, payable once.const report = await tuppence.paymentLinks.create({ name: "Research report", amount: 2000, currency: "eur" });
// A tip jar: the payer chooses between €1 and €50, and can pay repeatedly.const tips = await tuppence.paymentLinks.create({ name: "Tip jar", currency: "eur", min_amount: 100, max_amount: 5000, reusable: true,});
console.log(report.url, report.amount_type); // … fixedconsole.log(tips.url, tips.amount_type); // … customer_choosesimport osfrom tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
# A fixed price, payable once.report = tuppence.payment_links.create(name="Research report", amount=2000, currency="gbp")
# A tip jar: the payer chooses between £1 and £50, and can pay repeatedly.tips = tuppence.payment_links.create( name="Tip jar", currency="gbp", min_amount=100, max_amount=5000, reusable=True)
print(report.url, report.amount_type) # … fixedprint(tips.url, tips.amount_type) # … customer_chooses
# Later, find it by the start of its name.print([link.name for link in tuppence.payment_links.list(query="tip").data])import osfrom tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
# A fixed price, payable once.report = tuppence.payment_links.create(name="Research report", amount=2000, currency="usd")
# A tip jar: the payer chooses between $1 and $50, and can pay repeatedly.tips = tuppence.payment_links.create( name="Tip jar", currency="usd", min_amount=100, max_amount=5000, reusable=True)
print(report.url, report.amount_type) # … fixedprint(tips.url, tips.amount_type) # … customer_chooses
# Later, find it by the start of its name.print([link.name for link in tuppence.payment_links.list(query="tip").data])import osfrom tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
# A fixed price, payable once.report = tuppence.payment_links.create(name="Research report", amount=2000, currency="eur")
# A tip jar: the payer chooses between €1 and €50, and can pay repeatedly.tips = tuppence.payment_links.create( name="Tip jar", currency="eur", min_amount=100, max_amount=5000, reusable=True)
print(report.url, report.amount_type) # … fixedprint(tips.url, tips.amount_type) # … customer_chooses
# Later, find it by the start of its name.print([link.name for link in tuppence.payment_links.list(query="tip").data])Options
Section titled “Options”| Field | |
|---|---|
amount | A fixed amount. Leave it out to let the payer choose… |
min_amount, max_amount | …within these bounds (enforced by our server, not the page) |
reusable | true to take many payments. Otherwise it completes after one |
max_payments | For a reusable link, stop after this many |
expires_at | Unix seconds. After this, the link refuses payments |
completion_message, redirect_url | What the payer sees after paying. We follow redirect_url once the payment has succeeded. A Direct Debit is processing for a few working days, so its payer stays on our page, which confirms the debit is set up and when it will be collected |
metadata | Up to 50 keys of your own, copied onto each payment |
mode, plan | mode: "subscription" with a plan starts a subscription when paid |
application_fee_amount, application_fee_percent | Connect: your platform’s fee on each payment, set as the connected account |
POST /v1/payment_links/{id} updates the name, description, completion message, redirect or
metadata. GET /v1/payment_links?query= finds a link by its id or the start of its name, and
?status= filters by status.
Share it
Section titled “Share it”url | The payment page, with your business name, logo and colour (Settings → Branding) |
GET /v1/payment_links/{id}/qr | An SVG QR code of the url; ?format=png&size=512 for a PNG (size 64–1024) |
Stop it
Section titled “Stop it”status, or field | Means |
|---|---|
active | Takes payments |
completed | A single-use or max_payments link is used up. You receive payment_link.completed |
expires_at passed | The link refuses payments |
archived | You stopped it with POST /v1/payment_links/{id}/expire. Payments already made are unaffected |
paused_at, paused_reason | Our card-testing check paused it. After you’ve reviewed it, call POST /v1/payment_links/{id}/unpause |
payments_count and amount_collected track its progress.
- Webhooks: get notified of each payment.
- Subscriptions: a link that subscribes.