Manage payment methods and payments

You can create a payment method using the "Create a payment method" operation. However, to guarantee PCI-compliance, we recommend that you create payment methods using Zuora’s Payment Pages 2.0 feature.

Zuora’s Payment Pages allow end subscribers to send payment method details to your company in a secure and PCI-compliant manner. The payment page is hosted in Zuora and iframed directly onto your company’s website.

Payment Pages are usually embedded into the customer acquisition flow and shown to the end subscribers prior to an order submission. When the payment method details have been captured in Zuora, subsequent payments can be processed through that payment method.

The following diagram shows the default workflow of Zuora Payment Pages:

Payment Pages 2.0 flow

For more information, see Payment Pages 2.0 implementation overview.
Quickstart API
v1 API

Create payment methods

Suppose that you want to create a credit card payment method for your customer's account (account_id= 8ad093d07ae636bb017ae97518762aa3) and this card needs to be the default payment method on this account. You must configure the following fields:
  • type: Set this field to card.
  • card: Provide the credit card information as appropriate. The following fields are mandatory:
    • card_number
    • brand
    • expiry_month
    • expiry_year
  • account_id: Set this field to 8ad093d07ae636bb017ae97518762aa3, the unique identifier of this account.
curl --request POST \
  --url \
  --header 'Authorization: Bearer 723aa66a78384cb69ddb067fc448a776' \
  --header 'Content-Type: application/json' \
  --data '{
  "type": "card",
  "billing_details": {
    "name": "Amy Lawrence",
    "address": {
      "line1": "Apt 101, 123 Street",
      "city": "Atlanta",
      "state": "Georgia",
      "country": "USA"
  "card": {
    "card_number": "41111111111",
    "brand": "visa",
    "expiry_month": 11,
    "expiry_year": 2025,
    "security_code": "123"
  "is_default": true,
  "account_id": "8ad093d07ae636bb017ae97518762aa3"
Card cardInfo = new Card()
          .expiryMonth(new BigDecimal(11))
          .expiryYear(new BigDecimal(2025))

AddressFieldDefinitions addressInfo = new AddressFieldDefinitions()
        .line1("Apt 101, 123 Street")

BillingDetails billingDetails = new BillingDetails()
        .name("Amy Lawrence")

PaymentMethodCreateRequest paymentMethodInfo = new PaymentMethodCreateRequest()

PaymentMethod createdPaymentMethod = zuoraClient.paymentMethods().createPaymentMethod(paymentMethodInfo);

const cardInfo = {
  card_number: '41111111111',
  brand: 'visa',
  expiry_month: 11,
  expiry_year: 2025,
  security_code: '123'

const billingDetails = {
  name: 'Amy Lawrence',
      line1: 'Apt 101, 123 Street',
      city: 'Atlanta',
      state: 'Georgia',
      country: 'USA',

const paymentMethodInfo = {
  card: cardInfo,
  billing_details: billingDetails,
  type: 'card',
  is_default: true,
  account_id: '8ad093d07ae636bb017ae97518762aa3',

const creditCardRequest = await zuoraClient.paymentMethods.createPaymentMethod(paymentMethodInfo);


Create payment runs

After invoices have been created in the bill run, they are ready to collect payments. This is where payment runs come in: they are used to collect cash from your customers.

Suppose that you have created an ad hoc bill run (id=8ad094b98736ff1f01874b6f2f307eae) for a batch of your customers (Batch1), you can create a payment run for this batch to collect payment. In addition, you want to apply credit memos to their invoices before using their default payment methods.
curl --request POST \
  --url \
  --header 'Authorization: Bearer ac8a7ba092414c9c96c7243699ee6a6b' \
  --header 'Content-Type: application/json' \
  --data '{
	"apply_credit_memos": true,
	"target_date": "2023-04-01",
	"batch": "Batch1",
  	"bill_run_id": "8ad094b98736ff1f01874b6f2f307eae"

If the payment run request succeeds, you will get the following 201 Created response:
	"id": "8ad09e2087554ccb018755d12c7d4f62",
	"created_by_id": "8ad09bce80507dab0180688bdabc20cb",
	"created_time": "2023-04-06T02:06:24-07:00",
	"custom_fields": {},
	"custom_objects": {},
	"apply_credit_memos": true,
	"batch": "Batch1",
	"bill_run_id": "BR-00000128",
	"state_transitions": {},
	"payment_gateway_id": "",
	"payment_run_number": "PR-00000033",
	"payment_run_date": "2023-04-01",
	"target_date": "2023-04-01",
	"state": "pending"

Create payments

The Payment object holds all of the information about a payment, including the payment amount and to which billing documents the payment is applied.

The following code sample creates a payment to the invoice created for your customer account, Amy Lawrence (account_id=2c92c0f96abc17de016abd62bd0c5854), using the payment method (payment_method_id=8f64d4d7b1b989f6c571d931f84e0458) associated with this account.
curl -X POST ""
-H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
-H "Content-Type: application/json" 
-d '{ 
	"account_id": "2c92c0f96abc17de016abd62bd0c5854",
    "billing_documents": [{
		"id": "8ad093f27f54fa8d017f6b191ff02543",
		"amount": 50,
		"type": "invoice"
    "amount": 50,
    "currency": "USD",
    "payment_date": "2022-03-08",
    "payment_method_id": "8f64d4d7b1b989f6c571d931f84e0458",
    "external": true
LocalDate date = LocalDate.of(2022,3,8);

BillingDocumentApplicationRequest invoiceApplicationRequest = new BillingDocumentApplicationRequest()
    .amount(new BigDecimal(30))

PaymentCreateRequest paymentCreateRequest = new PaymentCreateRequest()
    .amount(new BigDecimal(50))

Payment newPayment = zuoraClient.payments().createPayment(paymentCreateRequest);
const invoiceApplicationRequest = {
    amount: 30,
    type: 'invoice',
    id: '8ad093f27f54fa8d017f6b191ff02543',
const paymentCreateRequest = {
    account_id: '2c92c0f96abc17de016abd62bd0c5854',
    amount: 50,
    payment_date: '2022-03-08',
    payment_method_id: '8f64d4d7b1b989f6c571d931f84e0458',
    external: true,
    currency: 'USD',
    billing_documents: [invoiceApplicationRequest]
const newPayment = await zuoraClient.payments.createPayment(paymentCreateRequest);

Create refunds

In Zuora, you can refund fully or partially unapplied payments to your end subscribers by refunding from payment.

When you issue a refund, the amount field is required, which represents the total amount of the refund.

The total amount of the refund cannot exceed the unapplied amount of the associated payment. If you want to refund the applied amount of the associated payment, you must first unapply the applied amount from the billing documents, and then refund the unapplied amount to your end subscribers.

The external filed indicates whether this refund is an external refund or an electronic refund. External refunds are performed outside of Zuora and electronic refunds are issued by using supported payment gateways.

If the refund type is electronic, you cannot specify the refund date because the electronic refund will automatically refund money to the end subscriber’s credit card.

The following example uses the Create a refund operation to refund part of the unapplied amount ($10) from the payment:

curl -X POST ""
     -H "Authorization: Bearer 6d151216ef504f65b8ff6e9e9e8356d3" 
     -H "Content-Type: application/json" 
     -d '{ 
            "account_id": "8ad09b7d8292b85d0182a4d6f875225a",
            "payment_id": "8ad0887e82d94f5d0182d967a49c1a63",
            "amount": 10,
            "external": false
String accountId = "8ad09b7d8292b85d0182a4d6f875225a";
String paymentId = newPayment.getId();

RefundCreateRequest refundRequest = new RefundCreateRequest()
    .amount(new BigDecimal(10))
Refund refund = zuoraClient.refunds().createRefund(refundRequest);
const refundRequest = {
    amount: 10,
    account_id: '8ad09b7d8292b85d0182a4d6f875225a',
    payment_id: '8ad0887e82d94f5d0182d967a49c1a63',
    external: false
const refund = await zuoraClient.refunds.createRefund(refundRequest);