These are the standards BlinkPay expects every Blink Payments and Blink Data integration to meet. Most of them cost nothing to adopt at the start and are expensive to retrofit, so build them in from your first sandbox call.
Your client ID and client secret belong on a server you control, never in a mobile app, a browser, a single-page application or any other front end. Anything shipped to a customer's device can be extracted from it. Your backend holds the credentials, requests access tokens and makes every BlinkPay API call. It is also the only place that decides what the customer is asked to approve: for Blink Payments, the amount and the payment reference (particulars, code and reference); for Blink Data, the permissions and the access period. Never accept those values from the app or the browser as they arrive.
Your app or web front end talks to your own backend, authenticated with your own user session or login tokens, not with BlinkPay credentials. Mobile Integration shows this architecture for native apps.
Never commit credentials to a repository, including private ones, and never paste them into tickets, chat or email. Keep them in a secret manager or secure parameter store, such as AWS Secrets Manager or SSM Parameter Store, Azure Key Vault or GCP Secret Manager, and inject them into your application at runtime. Limit who and what can read them, and keep sandbox and production credentials in separate entries so a test system can never pick up production keys.
The portal never displays an existing secret. Selecting Rotate Secret under Settings > API Settings generates a new one and shows it once, so copy it straight into your secret store (see Getting API Credentials).
Rotate the client secret when someone with access to it leaves, whenever you suspect it has been exposed, and periodically as part of your own key management. Only users with the Administrator or Developer role can rotate a secret, so review who holds those roles when staff change. When a production secret is rotated, BlinkPay emails your organisation's Administrators and Developers, which also tells you if someone rotates it unexpectedly.
Rotation takes effect immediately and there is no grace period: the old secret stops working for new token requests at once, while access tokens already issued remain valid until they expire. Plan the switch before you select Rotate Secret, so the new value goes into your secret store and your services pick it up straight away. See Credential Rotation.
Request an access token, cache it on your server and reuse it until shortly before it expires, rather than requesting one per API call (see Token Caching). Keep tokens in server memory or your secret store, never in a browser, a mobile app, a URL or a log.
Scopes are assigned to your API client by BlinkPay, based on the services you select when you apply, and the access token response lists the ones you hold. Select only the services you will use, and ask support@blinkpay.co.nz to remove access you no longer need. A leaked credential can only do what its scopes allow.
Every BlinkPay API call uses HTTPS, and requests over plain HTTP are refused. Use HTTPS for your own pages and endpoints that take part in the flow too: your return pages and, for the decoupled flow, your callback_url. Production rejects http:// redirect URLs.
Register the specific return path you use, not a bare domain. Path matching is by prefix on the raw string, so registering https://shop.example.com/ accepts every page on that host and https://shop.example.com/pay also accepts /payment-admin. Register a path that ends in a distinct segment, such as https://shop.example.com/blinkpay/return, use a wildcard subdomain only when you need one, and remove entries you no longer use. Sandbox and production keep separate lists, so a test URL registered in sandbox never applies to production. The matching rules are in Redirect URI Whitelisting.
The return redirect is a prompt to check, not proof of anything. Anyone can type your return URL with a cid and no status, and a genuine return may never arrive if the customer closes the browser. When the customer comes back, check that the cid matches the consent ID (or quick payment ID) you stored for that order, then call the API from your backend to read the actual status before you act on it. Branch on the status parameter, never on the error text, and never treat a value you don't recognise as success. The parameters are described in Return Parameters.
The decoupled flow's callback_url request is unsigned and carries only the consent ID, so treat it the same way: use it as a signal to read the consent from the API, never as the outcome itself.
Never log the client secret, access tokens or Authorization headers, and make sure your HTTP client, proxy and error-reporting tools don't capture them either. If you must record that a credential was used, mask it (for example, the last four characters). Treat customer details such as mobile numbers, account numbers and, for Blink Data, the account information you retrieve as personal information: log only what you need, masked where you can. To trace a Blink Payments request, log the request-id response header instead; support can find the request from it.
Blink Payments only: send an idempotency-key header on every request that creates a consent, payment or refund. The value must be a UUID; anything else is rejected with 400. Use a fresh key for each distinct payment and the same key when you retry the same request after a timeout or a 5xx, so a retry can never take the money twice. Gateway flow consents are de-duplicated on the request-id header instead, so send a UUID request-id with those and reuse it on a retry.