Test in the sandbox
The sandbox mirrors production with separate hosts and a set of test numbers that produce deterministic outcomes — so you can drive every delivery and consent path before touching real users.
| Surface | Sandbox | Local development |
|---|---|---|
| OAuth2 (PAS) | https://accounts.sandbox.ppoppo.com | http://localhost:3100 |
| External API (PCS) | https://api.sandbox.ppoppo.com/ext | localhost:3203 |
Test numbers
Send to these ppnums in the sandbox to force a specific outcome:
| ppnum | Behavior |
|---|---|
12300000001 | Delivered successfully |
12300000002 | Consent pending, then allowed |
12300000003 | Consent denied |
12300000004 | Delivery failure |
Test the sign-in flow
Generate a PKCE pair and exchange a code with curl:
CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=' | tr '/+' '_-')
CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" | openssl sha256 -binary | base64 | tr -d '=' | tr '/+' '_-')
# Open this URL in a browser to authorize, then copy the `code` from the redirect:
echo "https://accounts.sandbox.ppoppo.com/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/callback&response_type=code&scope=openid%20profile&state=test&code_challenge=$CODE_CHALLENGE&code_challenge_method=S256"
curl -X POST https://accounts.sandbox.ppoppo.com/oauth/token \
-d grant_type=authorization_code -d code=AUTH_CODE \
-d redirect_uri=http://localhost:3000/callback \
-d client_id=YOUR_CLIENT_ID -d code_verifier="$CODE_VERIFIER"Test the External API
Use grpcurl with a client_credentials JWT (obtain it by POSTing your External API client_id + client_secret to the token endpoint):
# Send to the "delivered" test number
grpcurl -H "authorization: Bearer $JWT" \
-d '{"template_id": "tpl_…", "recipients": [{"ppnum": "12300000001"}]}' \
api.sandbox.ppoppo.com/ext:443 \
chat.external.ExternalMessageService/CreateSendRequest
# Watch events as they arrive
grpcurl -H "authorization: Bearer $JWT" -d '{}' \
api.sandbox.ppoppo.com/ext:443 \
chat.external.ExternalMessageService/StreamSendRequestEventsPair the test numbers above with the event stream to confirm your consent and delivery handling end to end before switching to production.