Build and Test Your First Feature

Build a complete end-to-end payment flow in the sandbox — from creating a payment to confirming it's paid.

At this point, your API keys are confirmed and working. Now it's time to build a real payment flow in test mode before touching any live keys.

This guide walks through the most common integration pattern: accepting a card payment using the Payment Intents API.

What you'll build

A complete payment flow:

  1. Create a Payment Intent
  2. Attach a Payment Method (test card)
  3. Confirm the payment
  4. Verify the payment status

Step 1: Create a Payment Intent

A Payment Intent represents a payment your customer intends to make. Create one for the amount you want to charge.

curl -X POST https://api.paymongo.com/v1/payment_intents \
  -u sk_test_YOUR_TEST_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "attributes": {
        "amount": 10000,
        "currency": "PHP",
        "payment_method_allowed": ["card"],
        "capture_type": "automatic"
      }
    }
  }'
📘

amount is in centavos. 10000 = ₱100.00.

What you get back: a Payment Intent object with an id (e.g. pi_...) and a client_key. Save both — you'll need them in the next steps.


Step 2: Create a Payment Method

Attach a test card as the payment method.

curl -X POST https://api.paymongo.com/v1/payment_methods \
  -u sk_test_YOUR_TEST_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "attributes": {
        "type": "card",
        "details": {
          "card_number": "4343434343434345",
          "exp_month": 12,
          "exp_year": 2030,
          "cvc": "123"
        },
        "billing": {
          "name": "Test User",
          "email": "[email protected]"
        }
      }
    }
  }'

Test cards: Use 4343434343434345 for a successful payment. See the full list of test cards for other scenarios (declined, 3DS, etc.).

What you get back: a Payment Method object with an id (e.g. pm_...). Save it.


Step 3: Attach the Payment Method to the Intent

curl -X POST https://api.paymongo.com/v1/payment_intents/{PAYMENT_INTENT_ID}/attach \
  -u sk_test_YOUR_TEST_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "attributes": {
        "payment_method": "pm_YOUR_PAYMENT_METHOD_ID",
        "client_key": "YOUR_CLIENT_KEY",
        "return_url": "https://your-app.com/payment/complete"
      }
    }
  }'

Replace {PAYMENT_INTENT_ID} with the id from Step 1 and pm_YOUR_PAYMENT_METHOD_ID with the id from Step 2.


Step 4: Confirm the Payment Status

After attaching, check the Payment Intent to confirm the outcome.

curl https://api.paymongo.com/v1/payment_intents/{PAYMENT_INTENT_ID} \
  -u sk_test_YOUR_TEST_SECRET_KEY:

Look for status in the response:

StatusMeaning
awaiting_payment_methodNo payment method attached yet
awaiting_next_action3DS authentication required
processingPayment is being processed
succeededPayment confirmed — you're done
payment_failedPayment was declined

A succeeded status means your end-to-end flow is working.


Test Other Scenarios

Before going live, test the edge cases:

  • Declined card: Use 4111111111111111 to trigger a decline
  • 3DS required: Use 4120000000000007 to trigger 3DS authentication
  • Insufficient funds: Use 4000000000009995

Once you can successfully process a payment and handle a decline in test mode, you're ready for the Go-live Checklist.


What’s Next