What you’ll build

An agent flow that takes a name, an email, and a card token and produces a paid order — without juggling three separate tool calls.

The single call

Use create_customer_and_charge (a composite tool).

{
  "name": "create_customer_and_charge",
  "arguments": {
    "customer": {
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe",
      "phone": "+14155551234"
    },
    "billing_id": "card_visa",
    "amount": 2999,
    "currency": "usd",
    "metadata": { "plan_promo_code": "WELCOME10" },
    "idempotency_key": "onboard-2026-04-21-abc123"
  }
}

What EPD does internally:

Create the customer

Equivalent to create_customer with the customer block.

Attach the payment method

Equivalent to add_payment_method with billing_id and set_as_default: true.

Charge

Builds and charges an order behind the scenes — you pass the amount and currency directly and EPD wraps it into an order for you.

Return one consolidated response

Includes customer_id, payment_method_id, order_id, and the order status.

Why use the composite tool

Doing it yourselfcreate_customer_and_charge
3 MCP round-trips (≥ 3× latency)1 round-trip
Partial-failure recovery you write yourselfEPD orchestrates the flow and returns a consolidated outcome
3 idempotency keys to trackOne key per intent
3 request_ids to correlateOne logical trace by request_id

Handling outcomes

The response includes:

{
  "customer_id": "550e8400-e29b-41d4-a716-446655440000",
  "payment_method_id": "6ba7b815-9dad-11d1-80b4-00c04fd430c8",
  "order_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
  "order_status": "paid"
}

Or, if the charge declines:

{
  "customer_id": "550e8400-e29b-41d4-a716-446655440000",
  "payment_method_id": "6ba7b815-9dad-11d1-80b4-00c04fd430c8",
  "error": {
    "type": "processing_error",
    "code": "card_declined",
    "message": "Card was declined.",
    "request_id": "req_a1b2c3d4e5f67890abcdef0123456789"
  }
}

If the charge declines, the customer and payment method are still created — your agent can prompt for a different card and call create_order directly without re-creating the customer.

Sandbox example

Try with a declined token:

{
  "name": "create_customer_and_charge",
  "arguments": {
    "customer": {
      "email": "test@example.com",
      "first_name": "Decline",
      "last_name": "Test",
      "phone": "+14155550100"
    },
    "billing_id": "card_insufficient_funds",
    "amount": 1000,
    "currency": "usd"
  }
}

You’ll see the customer get created but the order fail with insufficient_funds.