> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://zuora.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://zuora.ferndocs.com/_mcp/server.

# Collect payments with payment form

This tutorial builds a working checkout that collects a card payment using Zuora's hosted Payment Form. Your server mints a short-lived payment session; the browser loads `zuora.js`, renders the form, and reports the result -- all without card data ever touching your backend.

> **Info**
>
> You'll need a Zuora **publishable key** (Settings > Payments > Payment Form) and a set of **OAuth credentials** (client ID and secret) for the server. Test with card `4111 1111 1111 1111`.

## Walkthrough

Scroll through the steps below. The code panel on the right follows along -- switching files and focusing the lines that matter for each step.

## Run it

1. Build the server: `mvn package`
2. Start it: `java -cp target/sample-jar-with-dependencies.jar com.zuora.sample.Server`
3. Open `http://localhost:8888/checkout.html` and pay with the test card.

On success, the customer is redirected to your return page with the resulting `paymentId`.

## What's next

* **Save the payment method** -- switch the payment session to a create-and-save flow to reuse the method for [recurring billing](/docs/guides/create-subscription).
* **Handle failures** -- inspect `result.error` in the `onComplete` callback to surface gateway decline reasons.
* **Go to production** -- pin a versioned `zuora.js` URL and swap the sandbox publishable key for your live key.