What you’ll do

By the end of this page you will have:

  1. Created a sandbox API key.
  2. Created a customer.
  3. Created a product to sell.
  4. Attached a sandbox card to that customer.
  5. Charged the card and seen a success response.

No real money moves. You can copy-paste each command and follow along.

Before you start

You need:

  • An EPD Commerce account (sign up if you do not have one).
  • A terminal with curl and uuidgen. Any HTTP client works — curl is just convenient.

Step 1 — Get a sandbox API key

Open the Merchant Portal

Go to commerce.epd.com and sign in.

Switch to your Demo Company

When you signed up, EPD also created a Demo Company alongside your real one. It is the sandbox — anything you do there moves no real money. Click your profile avatar (top right), hover the company name, and pick Demo Company from the list.

Create the key

Open the gear icon (top right) → API KeyCreate API Key. Give it a name like quickstart-local and (optionally) leave permissions at full access for now.

Copy the key

Because you created it inside the Demo Company, the key is automatically a sandbox key and starts with epd_test_sk_. It is shown once — store it somewhere safe.

export EPD_KEY="epd_test_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export EPD_VERSION="2026-02-11"

Step 2 — Create a customer

EPD requires a first name, last name, and a phone number on every customer (in international format with a leading + and country code, e.g. +14155551234). Email is required too.

curl https://api.epd.com/v1/customers \
  -H "Authorization: Bearer $EPD_KEY" \
  -H "epd-version: $EPD_VERSION" \
  -H "X-EPD-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "phone": "+14155551234"
  }'

You’ll get back a UUID id for the customer. Save it:

export CUSTOMER_ID="550e8400-e29b-41d4-a716-446655440000"

Step 3 — Create a product

Orders charge against products you’ve defined, not free-form amounts. Create a simple $20.00 digital product (no shipping):

curl https://api.epd.com/v1/products \
  -H "Authorization: Bearer $EPD_KEY" \
  -H "epd-version: $EPD_VERSION" \
  -H "X-EPD-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Quickstart Test Product",
    "sku": "quickstart-test-product",
    "description": "A throwaway product for the quickstart flow.",
    "pricing": { "amount": 2000, "currency": "usd" },
    "requires_shipping": false
  }'

Save the returned product UUID id:

export PRODUCT_ID="6ba7b810-9dad-11d1-80b4-00c04fd430c8"

Step 4 — Attach a sandbox card

EPD never accepts raw card numbers through this API. Instead, you pass a billing_id that points to a card stored in EPD Gateway. In sandbox, special tokens like card_visa stand in for real gateway vault ids.

curl https://api.epd.com/v1/customers/$CUSTOMER_ID/payment_methods \
  -H "Authorization: Bearer $EPD_KEY" \
  -H "epd-version: $EPD_VERSION" \
  -H "X-EPD-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "billing_id": "card_visa",
    "set_as_default": true
  }'

Save the returned payment-method UUID id:

export PM_ID="6ba7b815-9dad-11d1-80b4-00c04fd430c8"

Step 5 — Create an order

curl https://api.epd.com/v1/orders \
  -H "Authorization: Bearer $EPD_KEY" \
  -H "epd-version: $EPD_VERSION" \
  -H "X-EPD-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "'"$CUSTOMER_ID"'",
    "payment_method_id": "'"$PM_ID"'",
    "items": [
      { "product_id": "'"$PRODUCT_ID"'", "quantity": 1 }
    ]
  }'

You should receive a 201 Created with the order in succeeded state. If you have a webhook endpoint registered, an order.succeeded event will arrive shortly after.

Try this again with card_insufficient_funds instead of card_visa to see how a decline looks. The request returns a structured error you can show to a user.

Next steps