nuvei 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. nuvei-1.0.0/LICENSE +21 -0
  2. nuvei-1.0.0/PKG-INFO +598 -0
  3. nuvei-1.0.0/README.md +563 -0
  4. nuvei-1.0.0/nuvei/__init__.py +71 -0
  5. nuvei-1.0.0/nuvei/checksum.py +62 -0
  6. nuvei-1.0.0/nuvei/client.py +290 -0
  7. nuvei-1.0.0/nuvei/config.py +42 -0
  8. nuvei-1.0.0/nuvei/constants.py +45 -0
  9. nuvei-1.0.0/nuvei/exceptions.py +52 -0
  10. nuvei-1.0.0/nuvei/py.typed +0 -0
  11. nuvei-1.0.0/nuvei/services/__init__.py +1 -0
  12. nuvei-1.0.0/nuvei/services/advanced_apm.py +114 -0
  13. nuvei-1.0.0/nuvei/services/authentication.py +43 -0
  14. nuvei-1.0.0/nuvei/services/card_operations.py +61 -0
  15. nuvei-1.0.0/nuvei/services/financial.py +146 -0
  16. nuvei-1.0.0/nuvei/services/orders.py +84 -0
  17. nuvei-1.0.0/nuvei/services/payments.py +158 -0
  18. nuvei-1.0.0/nuvei/services/subscriptions.py +222 -0
  19. nuvei-1.0.0/nuvei/services/three_d_secure.py +95 -0
  20. nuvei-1.0.0/nuvei/services/user_payment_options.py +251 -0
  21. nuvei-1.0.0/nuvei/services/users.py +84 -0
  22. nuvei-1.0.0/nuvei/webhook.py +122 -0
  23. nuvei-1.0.0/nuvei.egg-info/PKG-INFO +598 -0
  24. nuvei-1.0.0/nuvei.egg-info/SOURCES.txt +44 -0
  25. nuvei-1.0.0/nuvei.egg-info/dependency_links.txt +1 -0
  26. nuvei-1.0.0/nuvei.egg-info/requires.txt +9 -0
  27. nuvei-1.0.0/nuvei.egg-info/top_level.txt +1 -0
  28. nuvei-1.0.0/pyproject.toml +65 -0
  29. nuvei-1.0.0/setup.cfg +4 -0
  30. nuvei-1.0.0/tests/test_async_client.py +123 -0
  31. nuvei-1.0.0/tests/test_checksum.py +76 -0
  32. nuvei-1.0.0/tests/test_checksum_integration.py +302 -0
  33. nuvei-1.0.0/tests/test_client.py +99 -0
  34. nuvei-1.0.0/tests/test_config.py +31 -0
  35. nuvei-1.0.0/tests/test_package.py +76 -0
  36. nuvei-1.0.0/tests/test_services_advanced_apm.py +61 -0
  37. nuvei-1.0.0/tests/test_services_authentication.py +43 -0
  38. nuvei-1.0.0/tests/test_services_card_operations.py +58 -0
  39. nuvei-1.0.0/tests/test_services_financial.py +120 -0
  40. nuvei-1.0.0/tests/test_services_orders.py +76 -0
  41. nuvei-1.0.0/tests/test_services_payments.py +124 -0
  42. nuvei-1.0.0/tests/test_services_subscriptions.py +168 -0
  43. nuvei-1.0.0/tests/test_services_three_d_secure.py +78 -0
  44. nuvei-1.0.0/tests/test_services_upo.py +193 -0
  45. nuvei-1.0.0/tests/test_services_users.py +69 -0
  46. nuvei-1.0.0/tests/test_webhook.py +71 -0
nuvei-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Krishan Jangid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
nuvei-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,598 @@
1
+ Metadata-Version: 2.4
2
+ Name: nuvei
3
+ Version: 1.0.0
4
+ Summary: Nuvei REST API v1.0 SDK for Python — payment processing, 3D Secure, subscriptions, and more.
5
+ Author: Krishan Jangid
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/krishanjangid/nuvei-python
8
+ Project-URL: Documentation, https://docs.nuvei.com
9
+ Project-URL: Repository, https://github.com/krishanjangid/nuvei-python
10
+ Project-URL: Changelog, https://github.com/krishanjangid/nuvei-python/blob/main/CHANGELOG.md
11
+ Keywords: nuvei,payment,gateway,credit-card,psp,3d-secure,subscription
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Office/Business :: Financial :: Point-Of-Sale
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: httpx<1.0,>=0.27.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8.0; extra == "dev"
29
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
30
+ Requires-Dist: pytest-httpx>=0.30; extra == "dev"
31
+ Requires-Dist: respx>=0.21; extra == "dev"
32
+ Requires-Dist: ruff>=0.4; extra == "dev"
33
+ Requires-Dist: mypy>=1.10; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # Nuvei Python SDK
37
+
38
+ A lightweight Python wrapper for the **Nuvei REST API v1.0** — authentication, payments, 3D Secure, financial operations, subscriptions, user & payment option management, all in one package.
39
+
40
+ ## Features
41
+
42
+ - **Full API v1.0 coverage** — authentication, payments, financial operations, 3D Secure, card operations, subscriptions, user & UPO management, advanced APM
43
+ - **Sync and async clients** — powered by `httpx`
44
+ - **Automatic checksum calculation** — SHA-256 (default) or MD5
45
+ - **Webhook/DMN verification** — validate `advanceResponseChecksum` on incoming notifications
46
+ - **Type-annotated** — full type hints with `py.typed` marker (PEP 561)
47
+ - **Minimal dependencies** — only `httpx`
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ pip install nuvei
53
+ ```
54
+
55
+ Or for development:
56
+
57
+ ```bash
58
+ pip install -e ".[dev]"
59
+ ```
60
+
61
+ ## Quick Start
62
+
63
+ ### Synchronous Usage
64
+
65
+ ```python
66
+ from nuvei import Nuvei
67
+
68
+ client = Nuvei(
69
+ merchant_id="your_merchant_id",
70
+ merchant_site_id="your_site_id",
71
+ merchant_secret_key="your_secret_key",
72
+ environment="test", # "prod", "test", "int", "qa"
73
+ )
74
+
75
+ # 1. Get a session token
76
+ session = client.get_session_token()
77
+ token = session["sessionToken"]
78
+
79
+ # 2. Open an order
80
+ order = client.open_order(amount="10.00", currency="USD")
81
+ order_token = order["sessionToken"]
82
+
83
+ # 3. Process a payment
84
+ result = client.payments.payment(
85
+ sessionToken=order_token,
86
+ amount="10.00",
87
+ currency="USD",
88
+ paymentOption={
89
+ "card": {
90
+ "cardNumber": "4111111111111111",
91
+ "cardHolderName": "John Doe",
92
+ "expirationMonth": "12",
93
+ "expirationYear": "2028",
94
+ "CVV": "217",
95
+ }
96
+ },
97
+ )
98
+ print(result["transactionId"], result["status"])
99
+ ```
100
+
101
+ ### Async Usage
102
+
103
+ ```python
104
+ import asyncio
105
+ from nuvei import AsyncNuvei
106
+
107
+ async def main():
108
+ async with AsyncNuvei(
109
+ merchant_id="your_merchant_id",
110
+ merchant_site_id="your_site_id",
111
+ merchant_secret_key="your_secret_key",
112
+ environment="test",
113
+ ) as client:
114
+ session = await client.get_session_token()
115
+ print(session["sessionToken"])
116
+
117
+ asyncio.run(main())
118
+ ```
119
+
120
+ ## Service Modules
121
+
122
+ Access API endpoints through organized service namespaces:
123
+
124
+ | Service | Accessor | Endpoints |
125
+ |---------|----------|-----------|
126
+ | **Authentication** | `client.authentication` | `get_session_token` |
127
+ | **Orders** | `client.orders` | `open_order`, `update_order`, `get_order_details` |
128
+ | **Payments** | `client.payments` | `payment`, `payment_cc`, `payment_apm`, `init_payment`, `get_payment_status`, `account_capture`, `get_mcp_rates`, `get_dcc_details` |
129
+ | **Financial** | `client.financial` | `settle_transaction`, `refund_transaction`, `void_transaction`, `payout`, `get_payout_status` |
130
+ | **3D Secure** | `client.three_d_secure` | `authorize3d`, `verify3d`, `dynamic3d` |
131
+ | **Card Operations** | `client.card_operations` | `card_tokenization`, `get_card_details` |
132
+ | **Users** | `client.users` | `create_user`, `update_user`, `get_user_details` |
133
+ | **UPOs** | `client.user_payment_options` | `add_upo_credit_card`, `add_upo_credit_card_by_temp_token`, `add_upo_credit_card_by_token`, `add_upo_apm`, `edit_upo_cc`, `edit_upo_apm`, `get_user_upos`, `delete_upo`, `suspend_upo`, `enable_upo`, `get_merchant_payment_methods` |
134
+ | **Subscriptions** | `client.subscriptions` | `create_plan`, `edit_plan`, `get_plans_list`, `create_subscription`, `edit_subscription`, `cancel_subscription`, `get_subscriptions_list`, `get_subscription_plans` |
135
+ | **Advanced APM** | `client.advanced_apm` | `add_bank_account`, `enroll_account`, `fund_account`, `get_account_details`, `get_document_url` |
136
+
137
+ ---
138
+
139
+ ## Integration Flows
140
+
141
+ ### Flow 1: Simple Payment (Sale)
142
+
143
+ The most common flow — charge a customer immediately.
144
+
145
+ ```python
146
+ from nuvei import Nuvei
147
+
148
+ client = Nuvei(
149
+ merchant_id="...", merchant_site_id="...",
150
+ merchant_secret_key="...", environment="test",
151
+ )
152
+
153
+ # Step 1: Open an order
154
+ order = client.open_order(amount="29.99", currency="USD")
155
+
156
+ # Step 2: Process the payment
157
+ result = client.payments.payment(
158
+ sessionToken=order["sessionToken"],
159
+ amount="29.99",
160
+ currency="USD",
161
+ transactionType="Sale",
162
+ paymentOption={
163
+ "card": {
164
+ "cardNumber": "4111111111111111",
165
+ "cardHolderName": "Jane Smith",
166
+ "expirationMonth": "12",
167
+ "expirationYear": "2028",
168
+ "CVV": "217",
169
+ }
170
+ },
171
+ deviceDetails={"ipAddress": "192.168.1.1"},
172
+ )
173
+
174
+ if result["status"] == "SUCCESS" and result["transactionStatus"] == "APPROVED":
175
+ print(f"Payment approved! Transaction ID: {result['transactionId']}")
176
+ ```
177
+
178
+ ### Flow 2: Auth and Settle
179
+
180
+ Authorize first, then settle (capture) later — common for e-commerce.
181
+
182
+ ```python
183
+ # Step 1: Open order
184
+ order = client.open_order(amount="100.00", currency="USD")
185
+
186
+ # Step 2: Authorize (hold funds, don't charge yet)
187
+ auth = client.payments.payment(
188
+ sessionToken=order["sessionToken"],
189
+ amount="100.00",
190
+ currency="USD",
191
+ transactionType="Auth",
192
+ paymentOption={
193
+ "card": {
194
+ "cardNumber": "4111111111111111",
195
+ "cardHolderName": "John Doe",
196
+ "expirationMonth": "12",
197
+ "expirationYear": "2028",
198
+ "CVV": "217",
199
+ }
200
+ },
201
+ )
202
+
203
+ # Step 3: Settle (capture) — can be full or partial amount
204
+ settle = client.financial.settle_transaction(
205
+ relatedTransactionId=auth["transactionId"],
206
+ amount="100.00", # or a partial amount like "50.00"
207
+ currency="USD",
208
+ authCode=auth["authCode"],
209
+ )
210
+ ```
211
+
212
+ ### Flow 3: Payment with 3D Secure (3DS 2.0)
213
+
214
+ Full 3DS flow for liability-shifted payments.
215
+
216
+ ```python
217
+ # Step 1: Open order
218
+ order = client.open_order(amount="50.00", currency="USD")
219
+
220
+ # Step 2: Init payment — check 3DS support
221
+ init = client.payments.init_payment(
222
+ sessionToken=order["sessionToken"],
223
+ amount="50.00",
224
+ currency="USD",
225
+ paymentOption={
226
+ "card": {
227
+ "cardNumber": "4000027891380961", # 3DS test card
228
+ "cardHolderName": "CL-BRW1",
229
+ "expirationMonth": "12",
230
+ "expirationYear": "2028",
231
+ "CVV": "217",
232
+ "threeD": {
233
+ "methodNotificationUrl": "https://your-site.com/3ds-notify",
234
+ },
235
+ }
236
+ },
237
+ )
238
+
239
+ # Step 3: Handle 3DS fingerprinting (client-side iframe)
240
+ # Render the threeD data from init["paymentOption"]["card"]["threeD"]
241
+
242
+ # Step 4: Authorize 3D (after challenge completion)
243
+ auth3d = client.three_d_secure.authorize3d(
244
+ sessionToken=order["sessionToken"],
245
+ amount="50.00",
246
+ currency="USD",
247
+ paymentOption={
248
+ "card": {
249
+ "threeD": {
250
+ # Include challenge result data here
251
+ }
252
+ }
253
+ },
254
+ relatedTransactionId=init["transactionId"],
255
+ )
256
+
257
+ # Step 5: Final payment with liability shift
258
+ payment = client.payments.payment(
259
+ sessionToken=order["sessionToken"],
260
+ amount="50.00",
261
+ currency="USD",
262
+ transactionType="Sale",
263
+ relatedTransactionId=auth3d["transactionId"],
264
+ paymentOption={
265
+ "card": {
266
+ "cardNumber": "4000027891380961",
267
+ "cardHolderName": "CL-BRW1",
268
+ "expirationMonth": "12",
269
+ "expirationYear": "2028",
270
+ "CVV": "217",
271
+ }
272
+ },
273
+ )
274
+ ```
275
+
276
+ ### Flow 4: Returning Customer (CIT / MIT with UPO)
277
+
278
+ Save a payment method after the first transaction, then use it for future payments.
279
+
280
+ ```python
281
+ # --- First-time payment: Customer-Initiated Transaction (CIT) ---
282
+
283
+ # Step 1: Create the user
284
+ client.users.create_user(
285
+ userTokenId="customer_12345",
286
+ countryCode="US",
287
+ firstName="Jane",
288
+ lastName="Smith",
289
+ email="jane@example.com",
290
+ )
291
+
292
+ # Step 2: Open order with userTokenId
293
+ order = client.open_order(
294
+ amount="49.99", currency="USD",
295
+ userTokenId="customer_12345",
296
+ )
297
+
298
+ # Step 3: Process first payment (card is saved automatically with userTokenId)
299
+ first_payment = client.payments.payment(
300
+ sessionToken=order["sessionToken"],
301
+ amount="49.99",
302
+ currency="USD",
303
+ transactionType="Sale",
304
+ userTokenId="customer_12345",
305
+ paymentOption={
306
+ "card": {
307
+ "cardNumber": "4111111111111111",
308
+ "cardHolderName": "Jane Smith",
309
+ "expirationMonth": "12",
310
+ "expirationYear": "2028",
311
+ "CVV": "217",
312
+ }
313
+ },
314
+ )
315
+
316
+ # Step 4: Get saved payment methods (UPOs)
317
+ upos = client.user_payment_options.get_user_upos(
318
+ userTokenId="customer_12345",
319
+ )
320
+ upo_id = upos["paymentMethods"][0]["userPaymentOptionId"]
321
+
322
+ # --- Future payment: Use saved UPO (CIT or MIT) ---
323
+
324
+ order2 = client.open_order(
325
+ amount="49.99", currency="USD",
326
+ userTokenId="customer_12345",
327
+ )
328
+
329
+ future_payment = client.payments.payment(
330
+ sessionToken=order2["sessionToken"],
331
+ amount="49.99",
332
+ currency="USD",
333
+ transactionType="Sale",
334
+ userTokenId="customer_12345",
335
+ paymentOption={"userPaymentOptionId": upo_id},
336
+ isRebilling="0", # "1" for MIT (merchant-initiated)
337
+ )
338
+ ```
339
+
340
+ ### Flow 5: Subscription / Rebilling
341
+
342
+ Set up automatic recurring payments.
343
+
344
+ ```python
345
+ # Step 1: Create a plan
346
+ plan = client.subscriptions.create_plan(
347
+ name="Premium Monthly",
348
+ initialAmount="0.00",
349
+ recurringAmount="29.99",
350
+ currency="USD",
351
+ endAfter={"day": "0", "month": "12", "year": "0"},
352
+ startAfter={"day": "0", "month": "1", "year": "0"},
353
+ )
354
+
355
+ # Step 2: Create a subscription for the user
356
+ sub = client.subscriptions.create_subscription(
357
+ userTokenId="customer_12345",
358
+ planId=plan["planId"],
359
+ userPaymentOptionId=upo_id,
360
+ initialAmount="0.00",
361
+ recurringAmount="29.99",
362
+ currency="USD",
363
+ endAfter={"day": "0", "month": "12", "year": "0"},
364
+ )
365
+
366
+ # Step 3: List active subscriptions
367
+ subs = client.subscriptions.get_subscriptions_list(
368
+ userTokenId="customer_12345",
369
+ subscriptionStatus="ACTIVE",
370
+ )
371
+
372
+ # Step 4: Cancel when needed
373
+ client.subscriptions.cancel_subscription(
374
+ subscriptionId=sub["subscriptionId"],
375
+ )
376
+ ```
377
+
378
+ ### Flow 6: Refund
379
+
380
+ ```python
381
+ # Full refund
382
+ refund = client.financial.refund_transaction(
383
+ relatedTransactionId="original_txn_id",
384
+ amount="49.99",
385
+ currency="USD",
386
+ clientUniqueId="refund-001",
387
+ authCode="original_auth_code",
388
+ )
389
+
390
+ # Partial refund
391
+ partial_refund = client.financial.refund_transaction(
392
+ relatedTransactionId="original_txn_id",
393
+ amount="10.00", # partial amount
394
+ currency="USD",
395
+ clientUniqueId="refund-002",
396
+ authCode="original_auth_code",
397
+ )
398
+ ```
399
+
400
+ ### Flow 7: Void
401
+
402
+ Cancel a transaction before settlement.
403
+
404
+ ```python
405
+ void = client.financial.void_transaction(
406
+ relatedTransactionId="original_txn_id",
407
+ amount="49.99",
408
+ currency="USD",
409
+ authCode="original_auth_code",
410
+ )
411
+ ```
412
+
413
+ ### Flow 8: Payout
414
+
415
+ Send money to a payment method (credit/disbursement).
416
+
417
+ ```python
418
+ payout = client.financial.payout(
419
+ userTokenId="customer_12345",
420
+ amount="100.00",
421
+ currency="USD",
422
+ userPaymentOption={"userPaymentOptionId": upo_id},
423
+ comment="Withdrawal payout",
424
+ )
425
+
426
+ # Check payout status
427
+ status = client.financial.get_payout_status(
428
+ clientRequestId=payout["clientRequestId"],
429
+ )
430
+ ```
431
+
432
+ ---
433
+
434
+ ## Webhook (DMN) Verification
435
+
436
+ Nuvei sends Direct Merchant Notifications (DMN) to your server after transaction events. Always verify the checksum.
437
+
438
+ ```python
439
+ from nuvei import verify_webhook
440
+
441
+ # In your webhook handler (Flask, FastAPI, Django, etc.)
442
+ def handle_nuvei_webhook(params: dict):
443
+ is_valid = verify_webhook(
444
+ params,
445
+ merchant_secret_key="your_secret_key",
446
+ raise_on_failure=False, # or True to raise ChecksumError
447
+ )
448
+ if is_valid:
449
+ txn_id = params.get("PPP_TransactionID")
450
+ status = params.get("Status")
451
+ # Process the notification...
452
+ ```
453
+
454
+ For custom DMN types with different field orderings:
455
+
456
+ ```python
457
+ from nuvei import verify_webhook_generic
458
+
459
+ verify_webhook_generic(
460
+ params,
461
+ merchant_secret_key="your_secret_key",
462
+ checksum_fields=["fieldA", "fieldB", "fieldC"],
463
+ checksum_param="advanceResponseChecksum",
464
+ secret_position="prefix", # or "suffix"
465
+ )
466
+ ```
467
+
468
+ ---
469
+
470
+ ## Configuration
471
+
472
+ ### Hash Algorithm
473
+
474
+ ```python
475
+ # Default is SHA-256; switch to MD5 if your account requires it
476
+ client = Nuvei(..., algorithm="md5")
477
+ ```
478
+
479
+ ### Environments
480
+
481
+ | Environment | Base URL |
482
+ |-------------|----------|
483
+ | `prod` | `https://secure.safecharge.com` |
484
+ | `test` | `https://ppp-test.nuvei.com` |
485
+ | `int` | `https://ppp-test.nuvei.com` |
486
+ | `qa` | `https://apmtest.gate2shop.com` |
487
+
488
+ ### Context Manager
489
+
490
+ ```python
491
+ # Auto-close the HTTP client
492
+ with Nuvei(...) as client:
493
+ session = client.get_session_token()
494
+ ```
495
+
496
+ ---
497
+
498
+ ## Error Handling
499
+
500
+ The SDK raises specific exceptions for different failure modes:
501
+
502
+ ```python
503
+ from nuvei import APIError, AuthenticationError, TransportError, ChecksumError
504
+
505
+ try:
506
+ result = client.payments.payment(...)
507
+ except AuthenticationError as e:
508
+ # Session token or credential issues
509
+ print(f"Auth failed: {e.reason}")
510
+ except APIError as e:
511
+ # Nuvei API returned an error
512
+ print(f"API error {e.err_code}: {e.reason}")
513
+ print(e.response_body) # full response dict
514
+ except TransportError as e:
515
+ # Network / HTTP-level errors
516
+ print(f"Network error: {e}")
517
+ ```
518
+
519
+ ### Response Handling
520
+
521
+ Every API method returns the full response dict from Nuvei. Check these fields:
522
+
523
+ | Field | Description |
524
+ |-------|-------------|
525
+ | `status` | `"SUCCESS"` or `"ERROR"` — indicates if the request was processed |
526
+ | `errCode` | `0` for success, non-zero for errors |
527
+ | `reason` | Human-readable error description |
528
+ | `transactionStatus` | `"APPROVED"`, `"DECLINED"`, `"PENDING"`, `"ERROR"` — actual transaction result |
529
+ | `transactionId` | Nuvei's unique transaction identifier |
530
+ | `authCode` | Authorization code from the issuer |
531
+ | `gwErrorCode` | Gateway-specific error code |
532
+ | `gwErrorReason` | Gateway-specific error description |
533
+
534
+ > **Important**: A `status: "SUCCESS"` means the request was processed — it does NOT mean the transaction was approved. Always check `transactionStatus` for the actual result.
535
+
536
+ For more details, see: [Nuvei Response Handling Guide](https://docs.nuvei.com/documentation/integration/response-handling/)
537
+
538
+ ---
539
+
540
+ ## Testing & Development
541
+
542
+ ### Running Tests
543
+
544
+ ```bash
545
+ pip install -e ".[dev]"
546
+ python -m pytest tests/ -v
547
+ ```
548
+
549
+ ### Testing Cards
550
+
551
+ Use these test card numbers in the **test** environment:
552
+
553
+ | Card Number | Brand | Behavior |
554
+ |-------------|-------|----------|
555
+ | `4111111111111111` | Visa | Approved |
556
+ | `5111111111111118` | Mastercard | Approved |
557
+ | `4000027891380961` | Visa | 3DS Challenge |
558
+ | `4000020951595032` | Visa | 3DS Frictionless |
559
+ | `4000023104662535` | Visa | Declined |
560
+
561
+ - **Expiry date**: Any future date (e.g. `12/2028`)
562
+ - **CVV**: Any 3 digits (e.g. `217`)
563
+
564
+ For the full list of testing cards, see: [Nuvei Testing Cards](https://docs.nuvei.com/documentation/integration/testing/testing-cards/)
565
+
566
+ ### Testing with Postman
567
+
568
+ Nuvei provides a Postman collection for testing API calls interactively:
569
+
570
+ 1. Import the Nuvei API collection into Postman
571
+ 2. Set environment variables: `merchantId`, `merchantSiteId`, `merchantSecretKey`
572
+ 3. Use the collection to test individual endpoints and verify responses
573
+
574
+ For details, see: [Testing APIs with Postman](https://docs.nuvei.com/documentation/integration/testing/testing-apis-with-postman/)
575
+
576
+ ---
577
+
578
+ ## Helpful Resources
579
+
580
+ | Resource | Link |
581
+ |----------|------|
582
+ | **Nuvei API v1.0 Reference** | [Main API Docs](https://docs.nuvei.com/api/main/indexMain_v1_0.html?json#Introduction) |
583
+ | **Advanced API Reference** | [Advanced API Docs](https://docs.nuvei.com/api/advanced/indexAdvanced.html?json#Introduction) |
584
+ | **Response Handling** | [Response Handling Guide](https://docs.nuvei.com/documentation/integration/response-handling/) |
585
+ | **Webhooks (DMN)** | [Webhook Documentation](https://docs.nuvei.com/documentation/integration/webhooks/) |
586
+ | **Testing Cards** | [Testing Cards Reference](https://docs.nuvei.com/documentation/integration/testing/testing-cards/) |
587
+ | **Testing with Postman** | [Postman Guide](https://docs.nuvei.com/documentation/integration/testing/testing-apis-with-postman/) |
588
+ | **3D Secure** | [3DS Documentation](https://docs.nuvei.com/documentation/features/3d-secure/) |
589
+ | **Financial Operations** | [Financial Ops Guide](https://docs.nuvei.com/documentation/features/financial-operations/) |
590
+ | **Subscription/Rebilling** | [Subscription Docs](https://docs.nuvei.com/documentation/features/subscription-rebilling/) |
591
+ | **Authentication** | [Auth Documentation](https://docs.nuvei.com/documentation/features/authentication/) |
592
+ | **Checksum Tool** | [Online Checksum Calculator](https://docs.nuvei.com/checksum-tool/) |
593
+
594
+ ---
595
+
596
+ ## License
597
+
598
+ MIT