SDKs
Every official Wajub package, what it needs to run, and which one your stack takes.
There is one Wajub API. Every package on this page is a thin wrapper over it, written in the idioms of its language, so nothing here does something the REST API cannot. What the wrappers buy you is authentication, retries, idempotency, typed errors and pagination that you would otherwise write once per project.
Most of this decision is made for you. The package follows from where your code runs, and the language follows from what you already write. What is left is checking that your runtime qualifies and that the package covers what you need.
Where your code runs
That question decides the package, and nothing else does.
| Your code runs | Reach for | Because |
|---|---|---|
| On your server | A server SDK | It holds the secret key, so it can do everything |
| In a browser | Wajub Components | It renders and confirms a checkout, nothing more |
| In a mobile app | A mobile SDK | It renders a native payment sheet |
| In a terminal | The CLI | Local webhook forwarding and test events, with a restricted rk. key |
| On WordPress | A plugin | No integration code at all |
| Nowhere yet | Payment Links or Invoice | A payable link, no code and no package |
| Anywhere else | The REST API | Every endpoint, documented for raw HTTP |
Most integrations use two: a server SDK to create the payment, and a browser or mobile package to collect it. That split is not a style choice, it is where the secret key is allowed to be.
One rule governs the whole list
The secret key stays on your server. Browsers and mobile apps receive a session token, scoped to
a single payment, produced by a server SDK. No package on this page changes that, and the API
answers 403 and emails the key's owner when a sk. key arrives from a browser. See
Sessions and security.
Server SDKs
Seven languages, one surface. They expose the same resources, so the difference between them is syntax rather than capability. PHP is at 2.0.1, Node.js and C# at 2.0.0, Ruby at 1.3.0, the others at 1.2.1.
| Language | Package | Registry | Version | Runtime |
|---|---|---|---|---|
| Node.js | @wajub/node | npm | 2.0.0 | Node 18+ |
| Python | wajub | PyPI | 1.2.1 | Python 3.10+, httpx |
| PHP | wajub/wajub-php | Packagist | 2.0.1 | PHP 8.4+, Guzzle 8.2 |
| Go | github.com/wajubhq/wajub-go | Go modules | v1.2.1 | Go 1.22+ |
| Ruby | wajub | RubyGems | 1.3.0 | Ruby 3.1+, no runtime gems |
| Java | com.wajub:wajub-java | Maven Central | 1.1.1 | Java 17+, OkHttp |
| C# and .NET | Wajub | NuGet | 1.1.1 | .NET 8+ |
Below the floor, call the REST API directly. It is HTTPS and JSON, and every endpoint on this site carries a raw example.
Python: install 1.2.1 or later
wajub 1.1.0 and 1.1.1 were published as an empty wheel, a py.typed marker and no module, so
import wajub raised ModuleNotFoundError. 1.2.1 is the first release that carries the package:
pip install "wajub>=1.2.1". Move any pin still on the two before it.
The same call, seven ways
Create a payment, get back a token for the browser and a URL for a redirect. This is the shape every server SDK shares.
curl https://api.wajub.com/payments \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{"amount": 15000, "currency": "XAF", "customer": {"email": "buyer@example.com"}}'Ruby, Java and C# read the same way in their own idiom. Each has its own page: Ruby, Java, C#.
What every server SDK gives you
The client is resource oriented. One object per API resource, the same names everywhere.
| Group | Resources |
|---|---|
| Money in | payments, refunds, disputes, links, invoices |
| Money out | transfers, beneficiaries, balance |
| People and accounts | customers, accounts, identity |
| Risk and compliance | shield, tax |
| Plumbing | events, webhooks, webhookEndpoints, listen, global |
Around them, the behaviour you would otherwise rebuild in every project.
- An
Idempotency-Keyis generated for every mutating call, and you can pass your own. - Retries on
429and5xx, with exponential backoff. - One error class per failure kind, so authentication, validation, rate limiting and transport failures are told apart before you read a message.
- Page based pagination with an iterator that fetches the next page for you.
- Webhook signature verification, so the endpoint that receives events is one call away from being safe.
- A Sync account reference per request, for platforms charging on behalf of their merchants.
Naming follows each language, snake_case in Python and Ruby, camelCase elsewhere (PHP methods
included, listRefunds), while the wire format stays snake_case. The mapping is on
SDK naming conventions.
In the browser
These render a checkout. They never hold a key, and they cannot refund, pay out or list anything. Your server creates the session first.
| Package | Framework | Needs at least | Version |
|---|---|---|---|
@wajub/js | Vanilla, bundler or CDN | A browser that understands ES2020, and an ESM bundler or the CDN script | 1.8.1 |
@wajub/react | React 18+, Next.js | React 18, React DOM 18 | 1.8.1 |
@wajub/vue | Vue 3.3+, Nuxt | Vue 3.3 | 1.8.1 |
@wajub/svelte | Svelte, SvelteKit | Svelte 4 or 5 | 1.8.1 |
@wajub/angular | Angular 17+, Angular SSR | Angular 17, @angular/core and @angular/common | 1.8.1 |
The four framework packages need @wajub/js installed beside them, 1.8.0 or later for
@wajub/angular. It is a peer dependency, not a bundled one.
The four framework packages are wrappers around @wajub/js, which is itself a small loader that
fetches the checkout runtime from https://js.wajub.com. The whole section has its own tree:
Wajub Components.
In a mobile app
A native payment sheet against a session your server created. The customer picks an operator, enters a number, and approves from their phone without leaving your app.
| Package | Platform | Version | Needs at least |
|---|---|---|---|
wajub_mobile | Flutter | 1.1.1 | Flutter 3.24, Dart 3.5 |
@wajub/react-native | React Native | 1.1.1 | React Native 0.74, React 18, @react-native-community/netinfo and @react-native-async-storage/async-storage. @stripe/stripe-react-native for Stripe cards only |
com.wajub:wajub-mobile-core | Kotlin, any JVM | 1.2.1 | Java 17, Kotlin 2.0 |
com.wajub:wajub-mobile-compose | Android | 1.2.1 | Android 7.0, API 24, and Jetpack Compose |
WajubMobileUI, WajubMobile | iOS | 1.0.0 | iOS 15, Swift 5.9, Xcode 15 |
Android ships as two artifacts, and you usually want both
wajub-mobile-core is a plain Kotlin and JVM library, no Android dependency, no manifest. It is
the API client and the checkout's logic. wajub-mobile-compose is the Android archive that carries the Material 3
payment sheet and depends on the core. Take core alone only when you are building the payment
interface yourself.
A payment sheet, not a merchant client
Mobile SDKs cover Payments and nothing else. Refunds, payouts, Billing, Sync, Shield and Tax stay on your server, where the secret key is. The shared architecture is on Mobile SDKs.
iOS ships as a Swift package
Two products of one Swift package, added with Swift Package Manager. WajubMobileUI carries the
SwiftUI payment sheet and brings WajubMobile with it, the Foundation-only API client and checkout
logic. Take WajubMobile alone when you build the payment interface yourself. Neither depends on
Stripe: a Stripe card goes through a CardCollector your app writes. See iOS.
What each package covers
Coverage follows from where the code runs, not from the language. All seven server SDKs expose the same eighteen resources under the same names, so there is no feature reason to prefer one.
Alongside those sit customers, identity, events, webhooks, webhookEndpoints, listen
and global, which every server SDK also carries.
Browser and mobile packages are not merchant clients
They render a payment against a session your server already created. There is no refund, no payout, no invoice and no account listing in them, and there will not be: those calls need the secret key, and the secret key never leaves your server. See Sessions and security.
A preview or beta label belongs to the product, never to the SDK. The clients do not gate
anything, so shield and tax are callable from every language today. Whether the product
behind them is ready for your account is on its own page.
Constraints worth knowing before you commit
Two more things are worth knowing, and neither is obvious from a package listing.
The Go module path is not what it looks like
The import path is github.com/wajubhq/wajub-go. The organisation is wajubhq, and
github.com/wajub/wajub-go resolves to nothing.
The Android group is com.wajub
Both Android artifacts are published under com.wajub, not co.wajub. A Gradle coordinate on
the wrong group simply fails to resolve.
On the command line
@wajub/cli is the only package here that is not for production code. It forwards webhooks to
your machine, triggers test events, and reads your API resources while you build.
| Package | Registry | Version | Runtime |
|---|---|---|---|
@wajub/cli | npm, Homebrew, Scoop | 1.7.3 | Node 22+ |
Installation and every command are on the CLI pages.
Without an SDK
Nothing on this page is required. Each SDK is a few thousand lines over HTTPS and JSON, and the API reference documents every endpoint with request and response examples. That is the right path for a language with no official package, for an environment you cannot add a dependency to, and for anyone who prefers to see the wire.
Two more things to decide
Picking the package is not the same as picking the integration. Two separate choices remain, and both have their own page.
| Decision | Where |
|---|---|
| Hosted page, inline embed, overlay, or your own fields | Choosing your payments integration |
| How API field names land in your language | SDK naming conventions |
Related pages
- SDK quickstartYour first API call, side by side in every language.
- Wajub ComponentsHosted checkout and payment fields in the browser.
- Naming conventionsHow snake_case API fields land in each language.
- Example appsClone a working project and point it at your keys.
- API authenticationPublishable, secret and restricted keys.
- Mobile SDKsThe contract the four mobile SDKs share.
- API referenceNo package needed, every endpoint for raw HTTP.