---
title: "Order now, pay later"
description: "Create orders without immediate payment, then collect funds when ready—perfect for pre-orders, approvals, and flexible checkout flows."
canonical: "https://studio.inttegro.com/guides/order-now-pay-later"
format: inttegro-machine-docs/v1
language: "Go"
sdk_version: "v11.0.1"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/go/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 490
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "curated"
recommended_mcp_tools: ["get_integration_guide","check_integration_readiness","create_order"]
estimated_tokens: 3638
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** Create an unpaid order now, start payment only when the business is ready, and verify the eventual outcome from that same order.

### Five questions

#### Q1. How is an order created without collecting money?

In [Create an order](https://studio.inttegro.com/machine/go/api/orders.md#create-an-order), set execute-payment to false or omit it. Save the returned order ID; creation records the purchase but does not contact a payment provider.

#### Q2. Which action starts collection later?

Use [Pay for an order](https://studio.inttegro.com/machine/go/api/orders.md#pay-for-an-order) against the existing order ID when inventory, approval, or timing permits. Do not create a second order merely to collect the first order's amount.

#### Q3. How is customer intent confirmed?

After payment starts, follow the returned next action and use [Confirm a payment](https://studio.inttegro.com/machine/go/api/orders.md#confirm-a-payment) when OTP is required. Starting payment and confirming it are separate from provider authorization.

#### Q4. What happens if the customer changes their mind or method?

Check the existing order state before any mutation. The guide's edge cases cover cancellation, a changed payment method, and expiry; the [Orders reference](https://studio.inttegro.com/machine/go/api/orders.md) owns which operations and states are currently permitted.

#### Q5. Which MCP tools fit this split workflow?

An authenticated client can use [create_order](https://studio.inttegro.com/machine/go/inttegro-mcp/tools.md#create_order) for the unpaid order and [send_order_invoice](https://studio.inttegro.com/machine/go/inttegro-mcp/tools.md#send_order_invoice) when collection is due. [pay_order](https://studio.inttegro.com/machine/go/inttegro-mcp/tools.md#pay_order) can start a payment after exact confirmation; [get_order](https://studio.inttegro.com/machine/go/inttegro-mcp/tools.md#get_order) tracks the result.

## Document content

# Order now, pay later

Sometimes you need to create an order before collecting payment—maybe you're confirming inventory, waiting for manager approval, or building a pre-order system. This guide shows you how to decouple order creation from payment execution, giving you complete control over when and how you charge customers.

> Mcp Guide Callout is interactive content. Use the canonical page to view it.

## How it works

The standard payment flow combines order creation and payment into one step, but Inttegro lets you split them apart. First, create an order with [`ExecutePayment`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#CreateParams.ExecutePayment): `false` (or omit it entirely) to capture the customer's intent without charging them. Later, when you're ready, call `/orders/pay` to initiate the charge, then confirm it with an OTP as usual. This pattern gives you flexibility while maintaining a complete audit trail from order creation through final payment.

## Step 1: create the order without payment

Create the order exactly as you would for immediate payment, but set [`ExecutePayment`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#CreateParams.ExecutePayment): `false` or leave out payment method details entirely. Inttegro creates the order, assigns it an ID, and saves all the details—but doesn't contact the payment provider yet. The order status starts at `"preparing"`, waiting for you to execute payment later.

**Create order — POST /orders/create**

```go
package main

import (
  "context"
  "log"
  "os"

  inttegro "github.com/inttegro/inttegro-sdk-go/v11"
  "github.com/inttegro/inttegro-sdk-go/v11/customer"
  "github.com/inttegro/inttegro-sdk-go/v11/money"
  "github.com/inttegro/inttegro-sdk-go/v11/order"
  "github.com/inttegro/inttegro-sdk-go/v11/price"
  "github.com/inttegro/inttegro-sdk-go/v11/product"
  "github.com/inttegro/inttegro-sdk-go/v11/request"
)

func main() {
  ctx := context.Background()
  client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))

  params := order.CreateParams{
    RequestMeta: &request.Meta{
      IdempotencyKey: "order_2025_001",
    },
    ExecutePayment: inttegro.Bool(false),
    CustomerData: &customer.Data{
      Name: "Gloria Kesewaa",
      Email: "gloria@example.com",
      PhoneNumber: "+233544998605",
    },
    LineItems: []order.LineItemParams{
      {
        Type: order.LineItemTypeProduct,
        Product: &order.ProductLineItemParams{
          Type: product.TypePhysical,
          Name: "Custom Furniture",
          Quantity: 1,
          Price: price.InlineParams{
            AmountParams: money.AmountParams{
              Currency: money.GHS,
              Value: 150000,
            },
          },
        },
      },
    },
  }
  result, err := client.Orders.Create(ctx, params)
  if err != nil {
    log.Fatal(err)
  }
  _ = result
}
```

### Response

> **Note:**
>
> This is a partial response showing key attributes. See the complete [Order
> object](https://studio.inttegro.com/machine/go/api/orders.md#the-order-object) for all available fields.

```json
{
  "order": {
    "id": "cPxZ9kL2mQrTfVqYz1wNbMxKs8dGhJ4p",
    "status": "preparing",
    "customer": {
      "id": "cu_abc123",
      "name": "Gloria Kesewaa",
      "email_address": "gloria@example.com"
    },
    "line_item_group": {
      "total": {
        "currency": "ghs",
        "value": 150000
      }
    }
  }
}
```

**Key attributes**:

- [`Order.ID`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order) - Save
  this—you'll use it to execute payment later
- [`Status`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order):
  `"preparing"`
  - Order exists but no payment initiated yet
- [`Payment`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order) object
  attached

## Step 2: execute payment when ready

When you're ready to collect payment—after confirming inventory, receiving approval, or whenever your business logic dictates—call `/orders/pay` with the order ID and payment method details. Inttegro contacts the mobile money provider, initiates the charge, and sends an OTP to the customer just like in the standard flow. You can provide new payment method details or reference a saved payment method if the customer has one.

**Execute payment — POST /orders/pay**

```go
package main

import (
  "context"
  "log"
  "os"

  inttegro "github.com/inttegro/inttegro-sdk-go/v11"
  "github.com/inttegro/inttegro-sdk-go/v11/order"
  "github.com/inttegro/inttegro-sdk-go/v11/paymentmethod"
)

func main() {
  ctx := context.Background()
  client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))

  params := order.PayParams{
    OrderID: "or_cPxZ9kL2mQrTfVqYz1wNbMxKs8dGhJ4p",
    PaymentMethodData: &paymentmethod.Data{
      Type: paymentmethod.TypeMobileMoney,
      MobileMoney: &paymentmethod.MobileMoneyParams{
        Network: paymentmethod.MobileMoneyNetworkMTN,
        AccountNumber: "0544998605",
      },
    },
  }
  result, err := client.Orders.Pay(ctx, params)
  if err != nil {
    log.Fatal(err)
  }
  _ = result
}
```

### Response

> **Note:**
>
> This is a partial response showing key attributes. See the complete [Order
> object](https://studio.inttegro.com/machine/go/api/orders.md#the-order-object) for all available fields.

```json
{
  "order": {
    "id": "cPxZ9kL2mQrTfVqYz1wNbMxKs8dGhJ4p",
    "status": "requires_payment",
    "payment": {
      "id": "py_xyz789",
      "status": "requires_action",
      "next_action": {
        "type": "confirm_payment",
        "confirm_payment": {
          "expires_at": "2025-01-13T10:08:00Z",
          "request": {
            "recipient": "0544998605",
            "sent_via": "sms"
          }
        }
      }
    }
  }
}
```

**What changed**:

- Now includes [`Payment`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order) object with payment intent details
- [`Payment.Status`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order):
  `"requires_action"`
  - OTP sent to customer
- Order status still `"requires_payment"` until OTP is confirmed

## Step 3: confirm payment with OTP

From here, the flow is identical to standard payments. The customer receives an OTP via SMS, enters it in your app, and you submit it to confirm the payment. Inttegro verifies the code, charges the mobile money account, and moves the order to `"paid"` status.

> **Note:**
>
> Confirmation is bound to one order, payment, and confirmation request. Use[`Order.Payment.ID`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order) as `payment_id` and[`Order.Payment.NextAction.ConfirmPayment.Request.ID`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#Order) as `confirmation_id`, then submit those values with [`OrderID`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#ConfirmParams.OrderID) and
> [`Token`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#ConfirmParams.Token).
> See [Confirm a payment](https://studio.inttegro.com/machine/go/api/orders.md#confirm-a-payment) for complete SDK examples.

## Common use cases

The create and pay operations above stay the same across these workflows. What
changes is the business condition that decides when your application pays or
cancels the order.

### Pre-orders with inventory confirmation

Create the unpaid order when the customer places the pre-order and store its ID
with your inventory reservation. Pay it after stock is confirmed. If the item
is unavailable, [cancel the order](https://studio.inttegro.com/machine/go/guides/cancel-an-order.md) and tell the customer
instead of leaving an open order behind.

### Manager approval workflows

Create the unpaid order before sending it through your approval process. Keep
the Inttegro order ID with the approval record, then pay only after approval.
Cancel declined requests so the order's state agrees with your internal record.

### Subscription setup before first charge

Create the unpaid first order so the customer can review the plan, price, and
billing date before money moves. Pay it after they accept. Schedule future
renewals only after that first payment succeeds.

### Layaway and installment plans

Keep the layaway plan in your own system and create a separate Inttegro order
for each installment. Each payment then has its own amount, idempotency key, and
lifecycle while still linking back to the same plan in your data.

## Handling edge cases

### Customer cancels before payment

Cancel the Inttegro order as well as updating your own record. This makes the
order terminal and prevents a later payment attempt against an order the
customer has abandoned. See [Cancel an order](https://studio.inttegro.com/machine/go/guides/cancel-an-order.md).

### Payment method changes between creation and payment

The customer can choose a different payment method before payment starts. Pass
the newly selected payment-method details when you pay the order; the order
does not need to be recreated.

### Order expires before payment

Set an expiration policy for unpaid orders. Look up the order before payment;
if it is outside your allowed window, cancel it and ask the customer to create a
new one rather than reviving stale prices or inventory decisions.

## Testing

Use an application configured for the test environment. Create a draft order, call [Pay for an order](https://studio.inttegro.com/machine/go/api/orders.md#pay-for-an-order) when your test workflow is ready to charge it, then inspect the returned order. If confirmation is required, follow [Confirm a payment](https://studio.inttegro.com/machine/go/api/orders.md#confirm-a-payment) with [`OrderID`](https://pkg.go.dev/github.com/inttegro/inttegro-sdk-go/v11@v11.0.1/order#ConfirmParams.OrderID), `payment_id`, `confirmation_id`, and the test token supplied for that environment.

## Key tips

**Track order state**: Since payment is deferred, maintain clear status tracking in your database. Use your own states—such as pending approval, awaiting inventory, or ready for payment—to record why each order is waiting.

**Set expiration policies**: Decide how long orders can remain unpaid before they expire. Common policies: 24 hours for standard orders, 7 days for pre-orders, 30 days for B2B approvals. Check age before executing payment.

**Communicate clearly**: Tell customers when they'll be charged. "You won't be charged until we confirm availability" or "Payment will be collected after manager approval." Set expectations upfront.

**Handle abandoned orders**: Not all created orders will result in payment. Set up automated processes to follow up on unpaid orders, remind customers, or clean up very old orders from your database.

## Next steps

- **[Accept a payment](https://studio.inttegro.com/machine/go/guides/accept-a-payment.md)** - Standard payment flow with immediate charging
- **[Retry a failed payment](https://studio.inttegro.com/machine/go/guides/retry-a-payment.md)** - Retry with alternative payment methods
- **[Charge repeat customers](https://studio.inttegro.com/machine/go/guides/charge-repeat-customers.md)** - Fast checkout for returning customers
- **[Orders API](https://studio.inttegro.com/machine/go/api/orders.md)** - Complete API reference

You now know how to decouple order creation from payment execution. This pattern gives you the flexibility to build pre-orders, approval workflows, and any scenario where charging happens after order creation.
