@citypay/sdk
v2.0.3
Published
The `@citypay/sdk` package is the public, framework‑friendly entry point for CityPay Elements. It safely loads the latest browser runtime and exposes a small, stable API for creating payment elements and running payment flows.
Downloads
403
Readme
@citypay/sdk — Facade (Integrator Guide)
The @citypay/sdk package is the public, framework‑friendly entry point for CityPay Elements.
It safely loads the latest browser runtime and exposes a small, stable API for creating payment
elements and running payment flows.
This facade takes care of loading and initialising the CityPay runtime in the browser, so you can focus on building your checkout.
Key features
- One import for the whole SDK:
@citypay/sdk - Auto‑loads the correct CityPay runtime in the browser (with integrity checking)
- Promise‑based bootstrap so you know exactly when the SDK is ready
- TypeScript types included
Install
npm install @citypay/sdk
# or
pnpm add @citypay/sdk
# or
yarn add @citypay/sdkQuick start (vanilla JS)
<!-- Your checkout page -->
<form id="pay-form">
<div id="cp-card-number"></div>
<div id="cp-card-exp"></div>
<div id="cp-card-cvc"></div>
<button type="submit">Pay</button>
<div id="errors"></div>
<pre id="result" hidden></pre>
</form>
<script type="module">
import { CityPayPromise } from '@citypay/sdk';
// 1) Load and initialise the CityPay runtime in the browser
const citypay = await CityPayPromise();
// 2) Create a payment element with hosted fields
// The exact field names/selectors may vary by integration mode.
const el = citypay.elements('auth', {
fields: {
cardNumber: '#cp-card-number',
cardExpiry: '#cp-card-exp',
cardCvc: '#cp-card-cvc',
}
});
// 3) Tokenise on submit
const form = document.getElementById('pay-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const { ok, token, error } = await el.tokenise();
if (!ok) {
document.getElementById('errors').textContent = error?.message || 'Payment details invalid';
return;
}
// Send token to your server to create/capture the payment
document.getElementById('result').hidden = false;
document.getElementById('result').textContent = JSON.stringify({ token }, null, 2);
});
</script>Notes:
- The
elements('auth', ...)example mirrors the SDK’s high‑level flow demonstrated in the root SDK docs. - Use your own UI and server integration to complete the payment using the tokenised details.
Using with frameworks (React example)
import { useEffect, useMemo, useState } from 'react';
import { CityPayPromise } from '@citypay/sdk';
export function Checkout() {
const [citypay, setCitypay] = useState<any>(null);
const [el, setEl] = useState<any>(null);
useEffect(() => {
let mounted = true;
CityPayPromise().then((cp) => {
if (!mounted) return;
setCitypay(cp);
const elements = cp.elements('auth', {
fields: {
cardNumber: '#card-number',
cardExpiry: '#card-exp',
cardCvc: '#card-cvc',
}
});
setEl(elements);
});
return () => { mounted = false; };
}, []);
const onSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!el) return;
const res = await el.tokenise();
// handle res.ok, res.token, res.error
};
return (
<form onSubmit={onSubmit}>
<div id="card-number" />
<div id="card-exp" />
<div id="card-cvc" />
<button type="submit">Pay</button>
</form>
);
}API surface exposed by the facade
From @citypay/sdk you can import:
CityPayPromise(opts?)— asynchronously loads the runtime and resolves with the CityPay API instance.- Re‑exports of core element APIs and types for convenience, including
CityPayElements,ElementsApi, and common option types. - Server‑side entry
CityPay(for server utilities; not used in the browser runtime).
If you’re using TypeScript, types are bundled and inferred automatically.
Bootstrapping and loader behaviour
Under the hood, CityPayPromise:
- Injects a small loader script into the page with Subresource Integrity (SRI) where applicable
- Waits for the runtime to finish booting
- Resolves to the CityPay API (also available on
window.citypaywhen ready)
You can pass optional parameters to control loading:
import { CityPayPromise } from '@citypay/sdk';
// All fields are optional
await CityPayPromise({
// Advanced usage only; typically you do not need to override these.
timeoutMs: 15000,
channel: 'prod', // or 'local' for development (disables SRI)
nonce: 'csp-nonce', // if your CSP requires nonces on scripts
debug: false,
attributes: { 'data-merchant': 'YOUR_MID' },
});Notes:
- In development you may set
channel: 'local'which disables SRI for local files. - If you use a Content Security Policy with nonces, provide
nonce.
SSR and environments
CityPayPromise must run in a browser (it touches document to append a <script> tag).
If you use SSR/SSG frameworks (Next.js, Nuxt, etc.), call it only on the client side, for example
inside a useEffect or a client‑only component.
Alt payments and advanced flows
The facade re‑exports option and response types for alternative payment methods and elements from the core package.
Consult the main SDK documentation for configuring Apple/Google Pay and other flows, then use the same types from
@citypay/sdk so you don’t need to import internal packages directly.
Error handling and troubleshooting
- If bootstrapping takes too long you’ll see a timeout error (default 15s). Increase
timeoutMsif your environment is slow. - Ensure the target field selectors you provide actually exist on the page before calling
elements(...). - For CSP issues, add the CityPay CDN to your
script-srcandconnect-srcdirectives and/or use anonce. - For local testing with strict CSP + SRI, consider
channel: 'local'during development.
Versioning
This facade always targets the latest compatible CityPay runtime. For stability across releases, pin your
@citypay/sdk version in your package manager (SemVer). Pre‑releases may be published with -next tags.
Support
If you need help integrating, please contact CityPay support with your merchant ID, the SDK version you’re using, and any relevant runtime logs or error messages.
