Skip to main content

Purchase Orders

Introduction

The Purchase Order service lets customers pay for an external order - created by an upstream partner system - directly from their Paysafe Embedded Wallet balance. The customer reaches the merchant application with a service code (for example a CIP code), the SDK resolves the order details, and the customer reviews and confirms the payment without leaving the host app.

Key Features

  • Simulate a purchase order to check fees and validate purchase order details without creating an actual transaction.
  • Perform necessary validations and initiate purchase order process.
  • Confirm the operation and move it to the processing stage, finalizing the payment flow.
  • Access a list of available purchase order methods for the customer.

Prerequisites

Before integrating the Purchase Order service, ensure you have:

  • A valid Paysafe account with appropriate permissions.
  • Set up instructions for Paysafe SDK Android or iOS.

To get started, initialize the PurchaseOrderService instance in your app as shown below:

import com.paysafe.wallet.android.core.wallet.Wallet

val purchaseOrderService = Wallet.getInstance().getPurchaseOrderService()

Purchase Order Workflow Overview

Purchase order mobile overviewPurchase order mobile overviewPurchase order mobile overviewPurchase order mobile overview

Purchase order steps

To complete purchase order, you will follow a three-step process: Validate the order details before creating the order. Lock in the order and prepare it for confirmation. Finalize and process the order payment.

1. Preview Purchase Order

The preview method is the first step in the purchase order process. It allows you to validate the purchase order parameters before actually creating the purchase order. This step creates a purchase order in PREVIEW state, which does not perform any transaction in the Paysafe Wallet system. Instead, it checks the purchase order's configuration.

Purpose: Validate the external serviceCode against the supported provider

Outcome: A Purchase Order object is returned, which is needed for the next steps.

note

The secure code required for the request must be obtained in advance. The value of the secure code will vary depending on the provider.

val request = PurchaseOrderRequest(
purchaseOrderDetails = PurchaseOrderDetails(
serviceCode = "1A2B3C4D5E",
provider = PurchaseOrderProvider.PAGO_EFECTIVO,
category = PurchaseOrderCategory.PURCHASE,
description = "Pedido en tienda en línea - referencia de compra #ORD-2026-88421"
)
)

val purchaseOrderId: String
try {
val preview = purchaseOrderService.preview(request)
purchaseOrderId = preview.id
// Display preview.amount, preview.currencyCode, preview.recipient, preview.fees to the customer
} catch (exception: Exception) {
// Handle error (for example PARTNER_NOT_AUTHORIZED, CUSTOMER_NOT_AUTHORIZED, invalid serviceCode)
return
}
2. Create Purchase Order

After the customer reviews the preview, call create to transition the purchase order from PREVIEW to PENDING. The SDK runs the required validations and the response carries the final paymentFunding distribution.

Purpose: Perform all required validations.

Outcome: The purchase order moves to PENDING and is ready to be confirmed.

val createRequest = PurchaseOrderCreate(
discounts = null,
paymentProperties = null
)

try {
val pending = purchaseOrderService.create(purchaseOrderId, createRequest)
// pending.status == PaymentStatus.PENDING
// pending.paymentFunding describes the wallet amount and applied discounts
} catch (exception: Exception) {
// Handle error (for example PURCHASE_ORDER_PREVIEW_EXPIRED)
return
}
3. Confirm Purchase Order

Confirm moves the purchase order from PENDING to PROCESSING. The customer's wallet is debited and the funds are routed to the external provider for settlement against the original service code.

Purpose: Commit the payment and trigger downstream processing by the external provider.

Outcome: The purchase order transitions to PROCESSING. When SCA is required, the SDK returns the purchase order with action = PaymentCompletionAction.SCA and scaDetails; the order stays in PENDING until the SCA challenge has been completed and confirm is called again with the scaDetails payload.

note

This operation might require Strong Customer Authentication (SCA). Please read Strong Customer Authentication for more information on the process. If the PurchaseOrder object returned by confirm has action: PaymentCompletionAction.SCA, the scaDetails will contain the SCA authentication properties needed to complete the process. Follow the steps outlined in Submit the SCA Authentication to confirm the event. After the SCA event is accepted, invoke confirm method again, providing scaDetails in the PurchaseOrderConfirm parameter.

val confirmRequest = PurchaseOrderConfirm(
scaDetails = null,
paymentProperties = null
)

runCatching {
purchaseOrderService.confirm(purchaseOrderId, confirmRequest)
}.onSuccess { purchaseOrder ->
purchaseOrder.scaDetails?.let { scaDetails ->
// Solve the SCA challenge with these details
// as described in https://docs.paysafe.com/docs/embedded-wallets/strong-customer-authentication
// Repeat the confirm call once the SCA challenge is solved.

val scaDetailsRequest = ScaAuthenticationEventRequest(
eventId = scaDetails.eventId,
walletOperationId = scaDetails.walletOperationId
)

purchaseOrderService.confirm(
purchaseOrderId,
PurchaseOrderConfirm(
scaDetails = scaDetailsRequest,
paymentProperties = null
)
)
} ?: // No scaDetails - the purchase order is confirmed and now in PROCESSING
}.onFailure { exception ->
// Handle error
}

Additional Methods

In addition to the methods that drive a single purchase order through its lifecycle, the Purchase Order service exposes read methods for inspecting historical orders.

Get a Purchase Orders List

Use getAll method to retrieve a paginated list of purchase orders for the current customer by passing the GetPurchaseOrdersParameters. Details about the object can be found here. If no parameters are passed, the last 10 purchase orders are returned by default.

val parameters = GetPurchaseOrdersParameters(
limit = 10,
offset = 0,
merchantRefNum = "67ad4ce7-6a5e-4767-9936-e063b912cc1d",
serviceCode = "1A2B3C4D5E",
slipId = "5009964049",
status = PaymentStatus.COMPLETED
)

try {
val purchaseOrderList = purchaseOrderService.getAll(parameters)
// purchaseOrderList.purchaseOrders and purchaseOrderList.meta (paging metadata)
} catch (exception: Exception) {
// Handle error
}

Get a Single Purchase Order

To retrieve the latest state of a specific purchase order.

val purchaseOrderId = "urn:purchase-order:7edd1e3b-e6e4-478a-942b-8c8ba6c06695"

try {
val purchaseOrder = purchaseOrderService.get(purchaseOrderId)
} catch (exception: Exception) {
// Handle error
}