COPYandPAY

COPYandPAY Integration Guide

A practical guide for preparing a checkout, rendering the hosted payment widget, and verifying payment status using Zimswitch Online.

How It Works

Three steps to a verified payment

Use COPYandPAY when you want hosted card entry with lower PCI scope and server-side status confirmation.

Step 1

Prepare the Checkout

Your server sends amount, currency, payment type and entity ID to the gateway. The gateway returns a checkout ID.

Step 2

Create the Payment Form

Load paymentWidgets.js with the checkout ID and render the hosted widget. The shopper enters payment details securely.

Step 3

Get Payment Status

After payment, verify the result server-side using resourcePath before fulfilling goods or services.

Important: Do not fulfil goods or services until payment status has been verified server-side. A browser redirect alone is not proof of payment.

Implementation progress

Credentials entered
Checkout prepared
Widget rendered / opened
Status verified

Current checkout ID
Security reminder

Never expose bearer tokens in frontend JavaScript. Prepare checkout and verify status on your server.

Interactive Credential Tester
Step 1

Prepare the checkout

Test your UAT credentials safely — your server requests a checkout ID from the gateway.

Credentials entered here are used only for this sandbox test and are not stored.

Zimswitch Online sets the return URL on the paymentWidgets form — not in the prepare-checkout request (recommended pattern).

Payment Widget
Step 2

Create the payment form

Add the widget script and form to your page, then let the shopper enter payment details in hosted fields.

Complete Step 1 first

Prepare a checkout above to unlock the widget snippets and live preview.

Checkout ready. Use checkout ID below.

Load the gateway widget library with your checkout ID.

<script src="https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId={{CHECKOUT_ID}}"></script>

Set the shopper return URL on the form action — not in the prepare-checkout request (recommended Zimswitch Online pattern).

<form action="{{SHOPPER_RESULT_URL}}" class="paymentWidgets" data-brands="{{PAYMENT_BRAND}}"></form>

Complete a test payment in the hosted widget below. After payment you will be redirected to your shopper result URL — copy the resourcePath for Step 3.

Verify Payment Status
Step 3

Confirm the final outcome server-side

After the shopper pays, verify the result using resourcePath before fulfilling goods or services.

Code Examples

Implementation snippets

1. Prepare checkout

curl -X POST '{{BASE_URL}}/v1/checkouts' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -d 'entityId={{ENTITY_ID}}' \ -d 'amount={{AMOUNT}}' \ -d 'currency={{CURRENCY}}' \ -d 'paymentType={{PAYMENT_TYPE}}' \ -d 'testMode=EXTERNAL'

2. Payment widget

<script src="{{BASE_URL}}/v1/paymentWidgets.js?checkoutId={{CHECKOUT_ID}}"></script> <form action="{{SHOPPER_RESULT_URL}}" class="paymentWidgets" data-brands="{{PAYMENT_BRAND}}"></form>

3. Verify status

curl -G '{{BASE_URL}}{{RESOURCE_PATH}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -d 'entityId={{ENTITY_ID}}'
<?php $data = http_build_query([ 'entityId' => '{{ENTITY_ID}}', 'amount' => '{{AMOUNT}}', 'currency' => '{{CURRENCY}}', 'paymentType' => '{{PAYMENT_TYPE}}', 'testMode' => 'EXTERNAL', ]); // POST to {{BASE_URL}}/v1/checkouts with Authorization: Bearer {{ACCESS_TOKEN}}
<script src="{{BASE_URL}}/v1/paymentWidgets.js?checkoutId={{CHECKOUT_ID}}"></script> <form action="{{SHOPPER_RESULT_URL}}" class="paymentWidgets" data-brands="{{PAYMENT_BRAND}}"></form>
curl -G '{{BASE_URL}}{{RESOURCE_PATH}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -d 'entityId={{ENTITY_ID}}'
await fetch('{{BASE_URL}}/v1/checkouts', { method: 'POST', headers: { Authorization: 'Bearer {{ACCESS_TOKEN}}' }, body: new URLSearchParams({ entityId: '{{ENTITY_ID}}', amount: '{{AMOUNT}}', currency: '{{CURRENCY}}', paymentType: '{{PAYMENT_TYPE}}', testMode: 'EXTERNAL', }), });

Run prepare + verify on your server. Do not ship bearer tokens to browsers.

const params = new URLSearchParams({ entityId: '{{ENTITY_ID}}', amount: '{{AMOUNT}}', currency: '{{CURRENCY}}', paymentType: '{{PAYMENT_TYPE}}', testMode: 'EXTERNAL', }); // Server-side POST only — never expose {{ACCESS_TOKEN}} in browser code.

Security & Compliance

Copy n Pay is designed for SAQ-A style hosted card entry — card data is entered in gateway-hosted fields.
Never store or log full PAN, CVV or PIN on your systems.
Keep entity ID and access token on the server only — never embed in client-side JavaScript.
Use HTTPS for all checkout and callback URLs.
Always verify payment status server-side; a redirect alone does not confirm payment.
Mask any card references in logs; store only gateway transaction IDs and your merchant references.

Common Mistakes

Treating the shopper redirect as proof of payment without server-side status verification.
Omitting entityId on status or checkout requests.
Using UAT credentials or endpoints in production (or vice versa).
Exposing bearer access tokens in frontend code or mobile apps.
Logging full gateway responses containing card data.
Fulfilling orders before amount and currency are verified against the original checkout.
Not handling checkout ID expiry after 30 minutes or after successful payment.

Testing Checklist

Go-Live Checklist