Quickstart
First successful API call in 5 minutes
Get to a real 2xx in under 5 minutes against the sandbox.
Create a sandbox merchant
Sign up at dashboard.505pay.link and follow the merchant-onboarding wizard. Sandbox merchants are auto-approved within seconds — no human KYB review.
After approval, note two values from Settings → General:
merchant_id— UUID, you pass it on every intent create.tenant_id— UUID, mostly informational; the API key implies the tenant.
Create a sandbox API key
Go to Settings → API Keys → Create. Pick:
- Name:
quickstart - Scopes:
payments.payment_intent.create,payments.payment_intent.read
The plaintext key (sk_test_…) is shown ONCE. Copy it into PAYOPS_SECRET_KEY in your env.
Create your first payment intent
export PAYOPS_SECRET_KEY="sk_test_..."
export PAYOPS_MERCHANT_ID="018f4d9f-7b8a-7c2d-9a2d-1f8b92f6d101"
curl -X POST https://sandbox.505pay.link/v1/payments/intents \
-H "Authorization: Bearer $PAYOPS_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quickstart-$(uuidgen)" \
-d '{
"merchant_id": "'"$PAYOPS_MERCHANT_ID"'",
"amount_idr": 10000,
"max_uses": 1,
"description": "Quickstart hello",
"allowed_channels": ["qris"]
}'const res = await fetch('https://sandbox.505pay.link/v1/payments/intents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAYOPS_SECRET_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': `quickstart-${crypto.randomUUID()}`,
},
body: JSON.stringify({
merchant_id: process.env.PAYOPS_MERCHANT_ID,
amount_idr: 10_000,
max_uses: 1,
description: 'Quickstart hello',
allowed_channels: ['qris'],
}),
});
console.log(await res.json());import os, uuid, requests
print(requests.post(
'https://sandbox.505pay.link/v1/payments/intents',
headers={
'Authorization': f"Bearer {os.environ['PAYOPS_SECRET_KEY']}",
'Idempotency-Key': f'quickstart-{uuid.uuid4()}',
},
json={
'merchant_id': os.environ['PAYOPS_MERCHANT_ID'],
'amount_idr': 10_000,
'max_uses': 1,
'description': 'Quickstart hello',
'allowed_channels': ['qris'],
},
timeout=10,
).json())$res = (new \GuzzleHttp\Client())->post(
'https://sandbox.505pay.link/v1/payments/intents',
[
'headers' => [
'Authorization' => 'Bearer ' . getenv('PAYOPS_SECRET_KEY'),
'Idempotency-Key' => 'quickstart-' . \Ramsey\Uuid\Uuid::uuid4(),
],
'json' => [
'merchant_id' => getenv('PAYOPS_MERCHANT_ID'),
'amount_idr' => 10000,
'max_uses' => 1,
'description' => 'Quickstart hello',
'allowed_channels' => ['qris'],
],
]
);
echo $res->getBody();body, _ := json.Marshal(map[string]any{
"merchant_id": os.Getenv("PAYOPS_MERCHANT_ID"),
"amount_idr": 10_000,
"max_uses": 1,
"description": "Quickstart hello",
"allowed_channels": []string{"qris"},
})
req, _ := http.NewRequest("POST",
"https://sandbox.505pay.link/v1/payments/intents",
bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("PAYOPS_SECRET_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "quickstart-"+uuid.New().String())
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)Expected (201 Created):
{
"id": "018f...",
"shortcode": "abc...",
"amount_idr": 10000,
"status": "open",
"checkout_url": "https://sandbox.505pay.link/pay/abc..."
}Open the checkout in your browser
Paste checkout_url into a browser tab. 505pay's hosted page renders the QR. In sandbox you can simulate completion from dashboard → Payments → Intents → simulate.
Next steps
- Accept your first payment — the full happy-path with webhook fulfilment
- Build a hosted checkout — same flow with a richer recipe + Express/Flask/Go examples
- Authentication guide — when to use API keys vs OAuth tokens
- Webhooks — verify HMAC signatures
- API Reference — Payments — every endpoint
Was this page helpful?