Redirect to Checkout

After creating a payment prompt, redirect your customer to the MiraclePay hosted checkout page where they can complete the payment.

Checkout URL Structure

The checkoutUrl returned from the Create Payment Prompt API depends on your account type. For standard accounts it has this format:

https://checkout.miraclecash.info/?sessionId=<prompt.id>

Example:

https://checkout.miraclecash.info/?sessionId=550e8400-e29b-41d4-a716-446655440000

US merchant accounts receive a different format:

https://checkout.miraclecash.info/checkout/pay/<prompt.id>

Note

Always redirect to the checkoutUrl value returned by the API — never construct the URL yourself. The host or format may change; the returned value is authoritative.

Redirect Methods

Client-Side Redirect

If your frontend calls your API, return the checkout URL for client-side redirect:

API Response:

{
  "success": true,
  "checkoutUrl": "https://checkout.miraclecash.info/?sessionId=550e8400..."
}

Frontend JavaScript:

async function handlePayment() {
  const response = await fetch('/api/create-payment', {
    method: 'POST',
    body: JSON.stringify({ amountCents: 5000, orderId: 'ORD-123' }),
  });

  const { checkoutUrl } = await response.json();

  // Redirect to MiraclePay checkout
  window.location.href = checkoutUrl;
}

Warning

Never call the External Payments API from the browser — the API secret must stay on your backend. The frontend should only ever receive the checkoutUrl.

Checkout Flow

Once redirected, the customer experiences this flow:

Your Site ──► MiraclePay Checkout ──► Select Wallet ──► Connect Wallet
                                                           │
                                                           ▼
                                                     Confirm Payment
                                                           │
                                                           ▼
                                                   Transaction Status
                                                      /         \
                                                 Success      Failed
                                                    │            │
                                                    ▼            ▼
                                            Payment Complete  Retry/Cancel

Checkout Page Features:

  1. Wallet Selection: Customer chooses their crypto wallet

  2. Amount Display: Shows payment amount in USD and crypto equivalent

  3. QR Code: For mobile wallet scanning

  4. Transaction Confirmation: Real-time status updates

  5. Expiration Timer: Shows remaining time to complete payment

Note

On US merchant accounts the checkout steps differ: the customer verifies their email, picks a network, and sends the displayed amount to the shown deposit address. The outcome is reported through the same payment statuses and webhooks.

Post-Payment Handling

Manual Polling (Without Redirect URL)

If you don't provide a redirectUrl, you need to verify the payment status yourself. The checkout page will show "You can now safely close this window" after completion.

Recommended approach:

  1. Before redirect: Show a "Processing payment..." page

  2. Track the outcome: Subscribe to Webhooks, or poll the payment status every few seconds

  3. Update order: Mark order as paid when status is successful

  4. Show confirmation: Display order confirmation to customer

Example polling implementation (getPayment is the signed helper from Checking Payment Status):

async function pollPaymentStatus(promptId) {
  const maxAttempts = 60; // 5 minutes at 5-second intervals
  let attempts = 0;

  while (attempts < maxAttempts) {
    const payment = await getPayment(promptId);

    switch (payment.status) {
      case 'successful':
        return { success: true, payment };
      case 'unsuccessful':
      case 'expired':
      case 'cancelled':
        return { success: false, payment };
      case 'pending':
        // Continue polling
        break;
    }

    await new Promise(resolve => setTimeout(resolve, 5000));
    attempts++;
  }

  throw new Error('Payment status polling timeout');
}

Tip

For server-to-server notification without polling, use Webhooks.

Payment Expiration

Every payment prompt carries an expiresAt timestamp; the expiry window is configured per blockchain network (typically minutes, not hours). If the customer doesn't complete payment in time:

  • The payment status changes to expired

  • The checkout URL becomes invalid

  • You should create a new payment prompt if the customer wants to retry

Tip

Read expiresAt from the payment object rather than assuming a fixed duration, and display the remaining time to customers.