Skip to main content

Getting started

This guide takes you from zero to your first signed API call - creating a checkout session - and verifying the signed response. If you would rather see a payment happen before you write any code, start with the Test UI below.

1. See a payment before you write code​

You don't need an API key to make your first test payment. The Test UI is a small web app where you fill in a form instead of building a request, and it creates a real hosted checkout for you. Every environment has one:

EnvironmentTest UIDashboardWhat happens when you pay
Sandboxhttps://test-ui.sandbox.upprove.comhttps://portal.sandbox.upprove.comTest providers, no money moves.
Livehttps://test-ui.upprove.comhttps://portal.upprove.comYour real providers, real money.

Sign in with the same email, password and verification code you use for the Orchestr Dashboard in that environment (the Dashboard column above). You need the Admin role on your account; if you can't get past the sign-in page, ask whoever set up your account to grant it.

Connect a provider​

A new account has no provider connected, so a checkout shows no payment methods until you add one. There is no built-in test provider: in Sandbox you connect a real provider with its own test credentials (for example Stripe's sk_test_… key), and nothing is charged.

In the Dashboard go to Payment Methods → Providers → Add Provider, pick a provider and enter its credentials. Then click Methods on the new provider card and enable the payment methods you want to offer. You need the Admin or Manager role for this.

If the provider only accepts API traffic from allowlisted IPs, add Orchestr's addresses in your provider account, or it will reject the requests Orchestr sends for you. Card acquirers use a separate PCI address. See IP addresses for the list for each environment.

Make a test payment​

With a provider connected, in the Test UI:

  • Pick a preset or type an amount, currency, customer and line items, then create the session.
  • You get a checkout link. Open it and pay the way your customer would.
  • Go back to the Dashboard: the session, order and transaction are there, and any webhook endpoint you registered has received the events. Nothing about it is special: it is the same session the API creates in step 4.
  • Every request you send is kept in the history panel, so you can copy the exact body that worked and reuse it as your first API call.
No payment methods on the checkout?

Methods are offered per country and currency from your provider configuration. If a session shows no methods, check the provider's currencies and the method's countries and currencies under Payment Methods in the Dashboard.

Live means live

On Live the Test UI runs against your real providers, and a completed payment is a real charge. Use it for a final check of your production setup, with an amount you are happy to refund.

The Test UI covers the hosted checkout and alternative payment methods. Card entry is not part of it; for cards, see Test cards.

2. Get your credentials​

From the Orchestr Dashboard, in the environment you want to use (Sandbox or Live), create:

  1. A secret API key (sk_test_… in Sandbox). Shown once - store it securely.
  2. A signing secret. Also shown once.

Export them so the examples below can read them:

export UPPROVE_SECRET_KEY="sk_test_..."
export UPPROVE_SIGNING_SECRET="your-signing-secret"

3. Know the basics​

  • Base URL (Sandbox): https://api.sandbox.upprove.com
  • All requests are JSON in snake_case.
  • Every request needs two headers: Authorization: Bearer <key> and a signed X-Signature (see Signing).

4. Create your first checkout session​

This POST /v1/checkout/sessions call creates a hosted checkout and returns a url to redirect your customer to. The examples reuse the buildSignatureHeader helper from the Signing guide.

Card payments are offered on the hosted page automatically - no extra integration. The card result (including the card token, and saving cards for later) arrives on your webhooks; see Cards on hosted checkout.

REQ_PATH="/v1/checkout/sessions"
BODY='{
"amount": "42.00",
"currency": "GBP",
"merchant_reference": "order-1001",
"success_url": "https://shop.example.com/ok",
"cancel_url": "https://shop.example.com/cancel",
"customer": {
"email": "jane@example.com"
}
}'
TS=$(date +%s)
SIG=$(printf '%s' "${TS}${REQ_PATH}${BODY}" \
| openssl dgst -sha256 -hmac "$UPPROVE_SIGNING_SECRET" | sed 's/^.*= //')

curl -sS -X POST "https://api.sandbox.upprove.com${REQ_PATH}" \
-H "Authorization: Bearer $UPPROVE_SECRET_KEY" \
-H "X-Signature: t=${TS}, v1=${SIG}" \
-H "Content-Type: application/json" \
--data-raw "$BODY"

If your account is set up with processing profiles, add "processing_profile": "<code>" to address the session to one of them. Leave it out to operate at account scope.

5. Read the response​

A 201 Created is returned with the checkout session. Redirect the customer to url:

{
"id": "cs_7e6d5c4b",
"url": "https://checkout.sandbox.upprove.com/cs_7e6d5c4b",
"status": "open",
"merchant_reference": "order-1001",
"order_id": "ord_5b4a3c2d",
"amount": 42.00,
"currency": "GBP",
"success_url": "https://shop.example.com/checkout/success",
"cancel_url": "https://shop.example.com/checkout/cancel",
"created_at": "2024-06-22T10:00:00Z"
}

The response carries an X-Signature header. Verify it before trusting the body - use the verification helper from Signing (the signed string for responses is timestamp + body).

Pre-selecting the payment method​

By default the hosted page lets the customer choose a country and then a payment method from everything you can route there. If the customer already chose the method on your page, pass it as the only entry of payment_methods - the hosted page then skips the selection and opens that method's form directly (for card, the card entry itself):

{
"amount": "42.00",
"currency": "EUR",
"merchant_reference": "order-1002",
"country": "DE",
"payment_methods": ["card"],
"success_url": "https://shop.example.com/ok",
"cancel_url": "https://shop.example.com/cancel",
"customer": {
"email": "jane@example.com"
}
}
  • payment_methods takes the same codes as POST /v1/payments (see Payment methods). Several entries narrow the list without skipping the selection.
  • country pins the checkout to one country, so the customer is not asked for it either. It must be a country in which at least one of the listed methods can be routed for the session currency, otherwise the request fails with country_not_available. Without it, the country is resolved from the customer's location and the list of countries offered shrinks to those the listed methods route in.
  • The session echoes both fields back, and the hosted page refuses any other method.

Going straight to the provider​

For a method that redirects to the provider's own page (paypal, skrill_wallet, ideal …), you can skip the hosted form entirely: add straight_through: true to a session confined to that single method, with a pinned country and a customer that already carries what the provider needs. Orchestr then submits the payment itself the first time the customer opens url, and the hosted page only forwards them to the provider.

{
"amount": "42.00",
"currency": "EUR",
"merchant_reference": "order-1003",
"country": "DE",
"payment_methods": ["paypal"],
"straight_through": true,
"success_url": "https://shop.example.com/ok",
"cancel_url": "https://shop.example.com/cancel",
"customer": {
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}
  • It is honoured only when all of these hold: payment_methods has exactly one entry and that method has requires_redirect: true on GET /v1/payment-methods and is not of type card or card_wallet; country is pinned; the method can be routed there for the session currency; and customer carries every field the routed provider requires (email, name or first_name/last_name, phone, billing_address as applicable).
  • A national document id cannot be sent at creation, so a method that needs one (most LATAM local methods) falls back to the form, which collects it.
  • The flag never fails the request. If a prerequisite is not met, the session is created as an ordinary checkout confined to that method and the response says straight_through: false - read it back rather than assume. Nothing is sent to the provider until the customer opens the checkout.
  • The customer still returns through the hosted page, so success_url, cancel_url, fail_url, retries after a decline and the checkout.session.* webhooks behave as on any other session.

6. Get notified of the outcome​

When the customer finishes paying, Orchestr sends a checkout.session.completed webhook. Register an endpoint in the Dashboard, verify the signature, and fulfil the order. One exception: a session created with capture_method: "manual" completes when the card is authorized, and the money moves only when you capture - fulfil on payment.succeeded instead; see Manual capture on hosted checkout.

Outcomes explains the session and transaction statuses, which ones are final, and the polling rule to follow when you cannot rely on the webhook.

Next steps​

  • Outcomes - the status model, webhooks first, and the polling rule.
  • Authentication and Signing in depth.
  • Direct payments - create a payment in one call, without a hosted session.
  • Webhooks to handle events.
  • The full API Reference.
  • Not sure what a field does? Recreate the case in the Test UI (step 1) and compare its request with yours.