Use PayPortal as your checkout
This guide shows you how to add a “Pay with card” button to your own website and send customers through PayPortal for secure payment.
Overview
PayPortal lets you accept card payments and settle in crypto without changing your existing site. You keep your current product pages and cart. When a customer is ready to pay, your backend calls our API, gets back a checkout URL, and your front end redirects them to PayPortal.
- You keep control of your website and cart.
- PayPortal hosts the checkout and handles the crypto side.
- You track orders and payouts from the PayPortal merchant dashboard.
https://api.payportal.uk
What you need
- An active PayPortal merchant account.
- Your PayPortal API key (starts with
pk_). - A backend server (Node, Python, PHP, etc.) that can make HTTP requests.
How it works
- Your site totals the order (cart total in USD).
- Your front end calls your backend, sending amount + optional customer/cart info.
- Your backend calls
/v1/checkout-sessionwith your PayPortal API key. - PayPortal returns a
checkoutUrlandsessionIdto your backend. - Your backend returns
checkoutUrlto the front end, which redirects the customer. - Once paid, the order shows up in your PayPortal dashboard with status and order details.
Step 1 – Front-end button (no API key)
This runs in your front end and calls your backend. Your PayPortal API key never appears in browser-side JavaScript.
<button id="payportal-btn">
Pay with card via PayPortal
</button>
<script>
async function startPayPortalCheckout() {
// Example: get cart total from your site
const cartTotal = 49.99; // replace with your real cart total in USD
// Optional: attach customer and cart details for your backend to forward
const payload = {
amount: cartTotal,
note: "Order #1234",
customer: {
name: "Customer Name",
email: "customer@example.com",
phone: "+1-555-123-4567",
address: {
line1: "123 Main St",
line2: "",
city: "Richmond",
state: "VA",
postalCode: "23220",
country: "US"
}
},
cart: [
{
sku: "SKU123",
name: "Example product",
quantity: 1,
unitPrice: 49.99
}
]
};
try {
// Call YOUR backend, not PayPortal directly
const res = await fetch("/create-payportal-checkout", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
const data = await res.json();
if (!res.ok || !data.checkoutUrl) {
console.error("Checkout error:", data);
alert("Could not create checkout. Please try again.");
return;
}
// Optional: data.sessionId if your backend forwards it
console.log("PayPortal sessionId:", data.sessionId);
// Redirect customer to PayPortal checkout
window.location.href = data.checkoutUrl;
} catch (err) {
console.error("Network error:", err);
alert("Network error. Please try again.");
}
}
document
.getElementById("payportal-btn")
.addEventListener("click", startPayPortalCheckout);
</script>
Request payload (from your backend to PayPortal)
| Field | Description |
|---|---|
amount
required
|
Total charge to the customer in USD as a number
(for example 49.99).
|
note
optional
|
Short description such as order number or customer name. |
customer
optional
|
Object with customer info:
name, email, phone,
address (line1, line2, city, state, postalCode, country).
|
cart
optional
|
Array of cart items. Each item:
{ sku, name, quantity, unitPrice }.
These show up in your PayPortal dashboard.
|
Response from PayPortal
Your backend will receive a JSON response similar to:
{
"checkoutUrl": "https://moonpay.hel.io/charge/...",
"sessionId": "69233...",
"baseAmount": 49.99
}
checkoutUrl is where you send the customer to pay.
sessionId is what you will see in the PayPortal dashboard.
baseAmount is the amount that will settle to your wallet
(before network fees).
Step 2 – Backend example (Node / Express)
This is an example of how your backend can call PayPortal using your API key. You can adapt this to any server framework or language.
// Node/Express example
import express from "express";
import fetch from "node-fetch";
const app = express();
app.use(express.json());
// Keep your PayPortal API key on the server only
const PAYPORTAL_API_KEY = "pk_YourPortalKeyHere";
app.post("/create-payportal-checkout", async (req, res) => {
try {
const payload = req.body; // { amount, note, customer, cart }
const ppRes = await fetch("https://api.payportal.uk/v1/checkout-session", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": PAYPORTAL_API_KEY
},
body: JSON.stringify(payload)
});
const data = await ppRes.json();
if (!ppRes.ok || !data.checkoutUrl) {
console.error("PayPortal error:", data);
return res.status(500).json({ error: "PayPortal checkout failed" });
}
// Forward only what the front end needs
res.json({
checkoutUrl: data.checkoutUrl,
sessionId: data.sessionId,
baseAmount: data.baseAmount
});
} catch (e) {
console.error(e);
res.status(500).json({ error: "Server error" });
}
});
// Start your server
app.listen(3000, () => {
console.log("Server listening on http://localhost:3000");
});
Step 3 – Match PayPortal sessions to your orders
If you run your own order system, you may want to link your internal order to the PayPortal payment. There are two easy ways to do this.
Option 1 – Use the note field
Set the note to your internal order number or identifier:
const payload = {
amount: cartTotal,
note: "Order #" + internalOrderId,
...
};
This note appears in the PayPortal dashboard when you view the transaction details, so you can quickly match them.
Option 2 – Store the sessionId
When you create a checkout session, PayPortal returns
sessionId. You can store that on your side next to the order.
const data = await res.json();
saveOrder({
orderId: internalOrderId,
payportalSessionId: data.sessionId
});
Later, when you look at the PayPortal dashboard, you can search by
sessionId to match an order.
Step 4 – View payments and mark orders fulfilled
-
When a customer starts checkout, the status is
pending. -
Once we confirm payment, the status becomes
completed. - You can log into your PayPortal merchant dashboard to see completed transaction count, settled totals, statuses and order details (customer info and cart items).
- You can mark an order as fulfilled in the dashboard after you ship or deliver it.
Security notes
- Never put your PayPortal API key in browser-side JavaScript or public HTML.
- Keep your API key on your server and call PayPortal from your backend only.
- Use HTTPS on your site, especially on checkout or account pages.
- Do not expose any private keys or wallets in your code.
Support
If you get stuck integrating PayPortal, send us:
- Your website URL.
- The code snippet you are using to call your backend endpoint (for example
/create-payportal-checkout). - The exact error message or screenshot of the browser console or network tab.
We can usually tell what is wrong just from that.