raqm-core 0.2.5__tar.gz → 0.3.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 (21) hide show
  1. {raqm_core-0.2.5 → raqm_core-0.3.0}/PKG-INFO +48 -18
  2. {raqm_core-0.2.5 → raqm_core-0.3.0}/README.md +47 -17
  3. {raqm_core-0.2.5 → raqm_core-0.3.0}/pyproject.toml +1 -1
  4. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/headers/jazzcash.py +2 -5
  5. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/jazzcash.py +5 -1
  6. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/schemas/jazzcash.py +12 -19
  7. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core.egg-info/PKG-INFO +48 -18
  8. {raqm_core-0.2.5 → raqm_core-0.3.0}/tests/test_easypaisa.py +7 -54
  9. {raqm_core-0.2.5 → raqm_core-0.3.0}/tests/test_jazzcash.py +4 -39
  10. {raqm_core-0.2.5 → raqm_core-0.3.0}/setup.cfg +0 -0
  11. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/__init__.py +0 -0
  12. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/easypaisa.py +0 -0
  13. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/exceptions/exceptions.py +0 -0
  14. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/headers/__init__.py +0 -0
  15. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/headers/easypaisa.py +0 -0
  16. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/schemas/__init__.py +0 -0
  17. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core/schemas/easypaisa.py +0 -0
  18. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core.egg-info/SOURCES.txt +0 -0
  19. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core.egg-info/dependency_links.txt +0 -0
  20. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core.egg-info/requires.txt +0 -0
  21. {raqm_core-0.2.5 → raqm_core-0.3.0}/src/raqm_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raqm-core
3
- Version: 0.2.5
3
+ Version: 0.3.0
4
4
  Summary: Unified Python SDK for Pakistani payment gateways (EasyPaisa, JazzCash, HBL, ABL, UBL, etc.)
5
5
  Classifier: Programming Language :: Python :: 3.9
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -19,7 +19,7 @@ Requires-Dist: pydantic>=2.0
19
19
 
20
20
  One async, type-safe interface across multiple processors — EasyPaisa, JazzCash, HBL, ABL, UBL, and more.
21
21
 
22
- > ⚠️ **Work in progress.** Currently only EasyPaisa is fully implemented. JazzCash is in progress. Contributions welcome!
22
+ > ⚠️ **Work in progress.** EasyPaisa and JazzCash (MWALLET) are implemented. Contributions welcome!
23
23
  >
24
24
  > ⚠️ **Breaking change in v0.2.4** — methods now **raise `PaymentError`** on business-level failures instead of returning a result with a non-success response code. Wrap calls in try/except to handle errors gracefully.
25
25
 
@@ -30,7 +30,7 @@ One async, type-safe interface across multiple processors — EasyPaisa, JazzCas
30
30
  | Gateway | Status |
31
31
  |---------|--------|
32
32
  | [EasyPaisa](https://easypaisa.com.pk) | ✅ Live |
33
- | [JazzCash](https://jazzcash.com.pk) | 🚧 In progress |
33
+ | [JazzCash](https://jazzcash.com.pk) | Live (MWALLET) |
34
34
  | HBL | 📅 Planned |
35
35
  | ABL | 📅 Planned |
36
36
  | UBL | 📅 Planned |
@@ -231,6 +231,7 @@ src/
231
231
  └── jazzcash.py # JazzCash Pydantic models
232
232
 
233
233
  tests/
234
+ ├── conftest.py # Shared fixtures & mock helpers
234
235
  ├── test_easypaisa.py # EasyPaisa integration tests
235
236
  ├── test_jazzcash.py # JazzCash integration tests
236
237
  └── headers/
@@ -303,24 +304,53 @@ class HBL:
303
304
 
304
305
  ### 5. Write integration tests
305
306
 
306
- `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses.
307
+ `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses. Add shared helpers to `tests/conftest.py`.
307
308
 
308
- ```python
309
- # tests/test_hbl.py
310
- import httpx
311
- import pytest
312
- from raqm_core import HBL
309
+ **conftest.py** — add a success body constant and a factory:
313
310
 
311
+ ```python
312
+ # tests/conftest.py
313
+ from raqm_core.hbl import HBL
314
+
315
+ HBL_SUCCESS_BODY = {
316
+ "orderId": "abc123",
317
+ "responseCode": "0000",
318
+ "responseDesc": "SUCCESS",
319
+ }
320
+
321
+ def make_hbl(response_body: dict) -> HBL:
322
+ return HBL(
323
+ api_key="test",
324
+ sandbox=True,
325
+ client=make_client(response_body),
326
+ )
327
+ ```
314
328
 
315
- @pytest.mark.asyncio
316
- async def test_pay_success():
317
- def handler(request: httpx.Request) -> httpx.Response:
318
- return httpx.Response(status_code=200, json={...})
329
+ **test file** — import from `conftest`:
319
330
 
320
- client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
321
- hbl = HBL(api_key="test", sandbox=True, client=client)
322
- result = await hbl.pay(...)
323
- assert result.responseCode == "0000"
331
+ ```python
332
+ # tests/test_hbl.py
333
+ import pytest
334
+ from raqm_core.exceptions.exceptions import PaymentError
335
+ from tests.conftest import HBL_SUCCESS_BODY, make_client, make_hbl
336
+
337
+
338
+ class TestPay:
339
+ @pytest.mark.asyncio
340
+ async def test_success(self):
341
+ hbl = make_hbl(HBL_SUCCESS_BODY)
342
+ result = await hbl.pay(...)
343
+ assert result.responseCode == "0000"
344
+
345
+ @pytest.mark.asyncio
346
+ async def test_network_error(self):
347
+ hbl = HBL(
348
+ api_key="test",
349
+ sandbox=True,
350
+ client=make_client({"error": "timeout"}, status_code=500),
351
+ )
352
+ with pytest.raises(NetworkError):
353
+ await hbl.pay(...)
324
354
  ```
325
355
 
326
356
  ### 6. Update this README
@@ -332,7 +362,7 @@ Add the new gateway to the **Supported Gateways** table with the appropriate sta
332
362
  ## Roadmap
333
363
 
334
364
  - [x] EasyPaisa (MA, OTC, inquiry)
335
- - [ ] JazzCash client + schemas
365
+ - [x] JazzCash client + schemas (MWALLET)
336
366
  - [ ] HBL payment gateway
337
367
  - [ ] ABL payment gateway
338
368
  - [ ] UBL payment gateway
@@ -4,7 +4,7 @@
4
4
 
5
5
  One async, type-safe interface across multiple processors — EasyPaisa, JazzCash, HBL, ABL, UBL, and more.
6
6
 
7
- > ⚠️ **Work in progress.** Currently only EasyPaisa is fully implemented. JazzCash is in progress. Contributions welcome!
7
+ > ⚠️ **Work in progress.** EasyPaisa and JazzCash (MWALLET) are implemented. Contributions welcome!
8
8
  >
9
9
  > ⚠️ **Breaking change in v0.2.4** — methods now **raise `PaymentError`** on business-level failures instead of returning a result with a non-success response code. Wrap calls in try/except to handle errors gracefully.
10
10
 
@@ -15,7 +15,7 @@ One async, type-safe interface across multiple processors — EasyPaisa, JazzCas
15
15
  | Gateway | Status |
16
16
  |---------|--------|
17
17
  | [EasyPaisa](https://easypaisa.com.pk) | ✅ Live |
18
- | [JazzCash](https://jazzcash.com.pk) | 🚧 In progress |
18
+ | [JazzCash](https://jazzcash.com.pk) | Live (MWALLET) |
19
19
  | HBL | 📅 Planned |
20
20
  | ABL | 📅 Planned |
21
21
  | UBL | 📅 Planned |
@@ -216,6 +216,7 @@ src/
216
216
  └── jazzcash.py # JazzCash Pydantic models
217
217
 
218
218
  tests/
219
+ ├── conftest.py # Shared fixtures & mock helpers
219
220
  ├── test_easypaisa.py # EasyPaisa integration tests
220
221
  ├── test_jazzcash.py # JazzCash integration tests
221
222
  └── headers/
@@ -288,24 +289,53 @@ class HBL:
288
289
 
289
290
  ### 5. Write integration tests
290
291
 
291
- `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses.
292
+ `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses. Add shared helpers to `tests/conftest.py`.
292
293
 
293
- ```python
294
- # tests/test_hbl.py
295
- import httpx
296
- import pytest
297
- from raqm_core import HBL
294
+ **conftest.py** — add a success body constant and a factory:
298
295
 
296
+ ```python
297
+ # tests/conftest.py
298
+ from raqm_core.hbl import HBL
299
+
300
+ HBL_SUCCESS_BODY = {
301
+ "orderId": "abc123",
302
+ "responseCode": "0000",
303
+ "responseDesc": "SUCCESS",
304
+ }
305
+
306
+ def make_hbl(response_body: dict) -> HBL:
307
+ return HBL(
308
+ api_key="test",
309
+ sandbox=True,
310
+ client=make_client(response_body),
311
+ )
312
+ ```
299
313
 
300
- @pytest.mark.asyncio
301
- async def test_pay_success():
302
- def handler(request: httpx.Request) -> httpx.Response:
303
- return httpx.Response(status_code=200, json={...})
314
+ **test file** — import from `conftest`:
304
315
 
305
- client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
306
- hbl = HBL(api_key="test", sandbox=True, client=client)
307
- result = await hbl.pay(...)
308
- assert result.responseCode == "0000"
316
+ ```python
317
+ # tests/test_hbl.py
318
+ import pytest
319
+ from raqm_core.exceptions.exceptions import PaymentError
320
+ from tests.conftest import HBL_SUCCESS_BODY, make_client, make_hbl
321
+
322
+
323
+ class TestPay:
324
+ @pytest.mark.asyncio
325
+ async def test_success(self):
326
+ hbl = make_hbl(HBL_SUCCESS_BODY)
327
+ result = await hbl.pay(...)
328
+ assert result.responseCode == "0000"
329
+
330
+ @pytest.mark.asyncio
331
+ async def test_network_error(self):
332
+ hbl = HBL(
333
+ api_key="test",
334
+ sandbox=True,
335
+ client=make_client({"error": "timeout"}, status_code=500),
336
+ )
337
+ with pytest.raises(NetworkError):
338
+ await hbl.pay(...)
309
339
  ```
310
340
 
311
341
  ### 6. Update this README
@@ -317,7 +347,7 @@ Add the new gateway to the **Supported Gateways** table with the appropriate sta
317
347
  ## Roadmap
318
348
 
319
349
  - [x] EasyPaisa (MA, OTC, inquiry)
320
- - [ ] JazzCash client + schemas
350
+ - [x] JazzCash client + schemas (MWALLET)
321
351
  - [ ] HBL payment gateway
322
352
  - [ ] ABL payment gateway
323
353
  - [ ] UBL payment gateway
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "raqm-core"
3
- version = "0.2.5"
3
+ version = "0.3.0"
4
4
  description = "Unified Python SDK for Pakistani payment gateways (EasyPaisa, JazzCash, HBL, ABL, UBL, etc.)"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -1,11 +1,8 @@
1
+ import hmac
1
2
  from hashlib import sha256
2
3
 
3
4
 
4
5
  def generate_secure_hash(hash_key: str, params: dict) -> str:
5
-
6
6
  values = "&".join(param[1] for param in sorted(params.items()) if param[1])
7
7
  my_str = hash_key + ("&" + values if values else "")
8
-
9
- my_bytes = str.encode(my_str)
10
- my_sha256 = sha256(my_bytes)
11
- return my_sha256.hexdigest()
8
+ return hmac.new(hash_key.encode(), my_str.encode(), sha256).hexdigest()
@@ -45,6 +45,7 @@ class JazzCash:
45
45
 
46
46
  async def pay_via_mwallet(
47
47
  self,
48
+ cnic: str,
48
49
  mobile_number: str,
49
50
  amount: str,
50
51
  description: str,
@@ -71,13 +72,16 @@ class JazzCash:
71
72
  pp_Description=description,
72
73
  pp_TxnExpiryDateTime=pp_TxnExpiryDateTime,
73
74
  pp_MobileNumber=mobile_number,
75
+ pp_CNIC=cnic,
74
76
  ) # type: ignore
75
77
 
76
78
  payload = request.model_dump()
77
79
  secure_hash = generate_secure_hash(hash_key=self.hash_key, params=payload)
78
80
 
79
81
  payload["pp_SecureHash"] = secure_hash
80
- data = await self._post(endpoint="DoMWalletTransaction", payload=payload)
82
+ data = await self._post(
83
+ endpoint="Purchase/DoMWalletTransaction", payload=payload
84
+ )
81
85
 
82
86
  result = JazzcashResponse(**data)
83
87
 
@@ -16,9 +16,6 @@ class JazzCashResponseCode(str, Enum):
16
16
  INSUFFICIENT_BALANCE = "405"
17
17
 
18
18
 
19
- # ── REQUEST MODELS ────────────────────────────────────────────────────────────
20
-
21
-
22
19
  class JazzcashRequest(BaseModel):
23
20
  pp_Version: str = Field("1.1", description="Payment Portal Version.")
24
21
  pp_Language: str = Field("EN", description="Display language. Fixed value 'EN'.")
@@ -29,10 +26,6 @@ class JazzcashRequest(BaseModel):
29
26
  "", description="Sub merchant ID, leave empty if unused."
30
27
  )
31
28
  pp_Password: str = Field(..., description="Password assigned by JazzCash.")
32
- pp_BankID: str = Field("", description="Bank identifier, leave empty if unused.")
33
- pp_ProductID: str = Field(
34
- "", description="Product identifier, leave empty if unused."
35
- )
36
29
  pp_TxnRefNo: str = Field(..., description="Unique transaction reference number.")
37
30
  pp_Amount: str = Field(..., description="Transaction amount, no decimal places.")
38
31
  pp_TxnCurrency: str = Field(
@@ -56,15 +49,17 @@ class JazzcashRequest(BaseModel):
56
49
  class JazzcashMWalletRequest(JazzcashRequest):
57
50
  pp_TxnType: str = Field("MWALLET", description="Transaction type.")
58
51
  pp_MobileNumber: str = Field(..., description="Customer's JazzCash mobile number.")
59
-
60
-
61
- # ── RESPONSE MODELS ───────────────────────────────────────────────────────────
52
+ pp_CNIC: str = Field(
53
+ ..., min_length=6, max_length=6, description="Last 6 digits of customer's CNIC."
54
+ )
55
+ pp_DiscountedAmount: str = Field(
56
+ "", description="Discounted amount, leave empty if unused."
57
+ )
62
58
 
63
59
 
64
60
  class JazzcashResponse(BaseModel):
65
61
  pp_Amount: str = Field(..., description="Transaction amount.")
66
62
  pp_AuthCode: Optional[str] = None
67
- pp_BankID: Optional[str] = None
68
63
  pp_BillReference: Optional[str] = None
69
64
  pp_Language: Optional[str] = None
70
65
  pp_MerchantID: str = Field(..., description="Merchant ID.")
@@ -72,19 +67,17 @@ class JazzcashResponse(BaseModel):
72
67
  ..., description="Response code."
73
68
  )
74
69
  pp_ResponseMessage: str = Field(..., description="Response message.")
75
- pp_RetreivalReferenceNo: Optional[str] = None
76
- pp_SubMerchantId: Optional[str] = None
70
+ pp_RetrievalReferenceNo: Optional[str] = None # fixed JazzCash typo from v1
71
+ pp_RetreivalReferenceNo: Optional[str] = None # kept for v1 backwards compat
72
+ pp_SubMerchantID: Optional[str] = None
77
73
  pp_TxnCurrency: Optional[str] = None
78
74
  pp_TxnDateTime: Optional[str] = None
79
75
  pp_TxnRefNo: str = Field(..., description="Transaction reference number.")
80
- pp_SettlementExpiry: Optional[str] = None
81
76
  pp_TxnType: Optional[str] = None
82
77
  pp_Version: Optional[str] = None
83
- ppmbf_1: Optional[str] = None
84
- ppmbf_2: Optional[str] = None
85
- ppmbf_3: Optional[str] = None
86
- ppmbf_4: Optional[str] = None
87
- ppmbf_5: Optional[str] = None
78
+ pp_MobileNumber: Optional[str] = None
79
+ pp_CNIC: Optional[str] = None
80
+ pp_DiscountedAmount: Optional[str] = None
88
81
  ppmpf_1: Optional[str] = None
89
82
  ppmpf_2: Optional[str] = None
90
83
  ppmpf_3: Optional[str] = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: raqm-core
3
- Version: 0.2.5
3
+ Version: 0.3.0
4
4
  Summary: Unified Python SDK for Pakistani payment gateways (EasyPaisa, JazzCash, HBL, ABL, UBL, etc.)
5
5
  Classifier: Programming Language :: Python :: 3.9
6
6
  Classifier: Programming Language :: Python :: 3.10
@@ -19,7 +19,7 @@ Requires-Dist: pydantic>=2.0
19
19
 
20
20
  One async, type-safe interface across multiple processors — EasyPaisa, JazzCash, HBL, ABL, UBL, and more.
21
21
 
22
- > ⚠️ **Work in progress.** Currently only EasyPaisa is fully implemented. JazzCash is in progress. Contributions welcome!
22
+ > ⚠️ **Work in progress.** EasyPaisa and JazzCash (MWALLET) are implemented. Contributions welcome!
23
23
  >
24
24
  > ⚠️ **Breaking change in v0.2.4** — methods now **raise `PaymentError`** on business-level failures instead of returning a result with a non-success response code. Wrap calls in try/except to handle errors gracefully.
25
25
 
@@ -30,7 +30,7 @@ One async, type-safe interface across multiple processors — EasyPaisa, JazzCas
30
30
  | Gateway | Status |
31
31
  |---------|--------|
32
32
  | [EasyPaisa](https://easypaisa.com.pk) | ✅ Live |
33
- | [JazzCash](https://jazzcash.com.pk) | 🚧 In progress |
33
+ | [JazzCash](https://jazzcash.com.pk) | Live (MWALLET) |
34
34
  | HBL | 📅 Planned |
35
35
  | ABL | 📅 Planned |
36
36
  | UBL | 📅 Planned |
@@ -231,6 +231,7 @@ src/
231
231
  └── jazzcash.py # JazzCash Pydantic models
232
232
 
233
233
  tests/
234
+ ├── conftest.py # Shared fixtures & mock helpers
234
235
  ├── test_easypaisa.py # EasyPaisa integration tests
235
236
  ├── test_jazzcash.py # JazzCash integration tests
236
237
  └── headers/
@@ -303,24 +304,53 @@ class HBL:
303
304
 
304
305
  ### 5. Write integration tests
305
306
 
306
- `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses.
307
+ `tests/test_<gateway>.py` — use `httpx.MockTransport` to mock responses. Add shared helpers to `tests/conftest.py`.
307
308
 
308
- ```python
309
- # tests/test_hbl.py
310
- import httpx
311
- import pytest
312
- from raqm_core import HBL
309
+ **conftest.py** — add a success body constant and a factory:
313
310
 
311
+ ```python
312
+ # tests/conftest.py
313
+ from raqm_core.hbl import HBL
314
+
315
+ HBL_SUCCESS_BODY = {
316
+ "orderId": "abc123",
317
+ "responseCode": "0000",
318
+ "responseDesc": "SUCCESS",
319
+ }
320
+
321
+ def make_hbl(response_body: dict) -> HBL:
322
+ return HBL(
323
+ api_key="test",
324
+ sandbox=True,
325
+ client=make_client(response_body),
326
+ )
327
+ ```
314
328
 
315
- @pytest.mark.asyncio
316
- async def test_pay_success():
317
- def handler(request: httpx.Request) -> httpx.Response:
318
- return httpx.Response(status_code=200, json={...})
329
+ **test file** — import from `conftest`:
319
330
 
320
- client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
321
- hbl = HBL(api_key="test", sandbox=True, client=client)
322
- result = await hbl.pay(...)
323
- assert result.responseCode == "0000"
331
+ ```python
332
+ # tests/test_hbl.py
333
+ import pytest
334
+ from raqm_core.exceptions.exceptions import PaymentError
335
+ from tests.conftest import HBL_SUCCESS_BODY, make_client, make_hbl
336
+
337
+
338
+ class TestPay:
339
+ @pytest.mark.asyncio
340
+ async def test_success(self):
341
+ hbl = make_hbl(HBL_SUCCESS_BODY)
342
+ result = await hbl.pay(...)
343
+ assert result.responseCode == "0000"
344
+
345
+ @pytest.mark.asyncio
346
+ async def test_network_error(self):
347
+ hbl = HBL(
348
+ api_key="test",
349
+ sandbox=True,
350
+ client=make_client({"error": "timeout"}, status_code=500),
351
+ )
352
+ with pytest.raises(NetworkError):
353
+ await hbl.pay(...)
324
354
  ```
325
355
 
326
356
  ### 6. Update this README
@@ -332,7 +362,7 @@ Add the new gateway to the **Supported Gateways** table with the appropriate sta
332
362
  ## Roadmap
333
363
 
334
364
  - [x] EasyPaisa (MA, OTC, inquiry)
335
- - [ ] JazzCash client + schemas
365
+ - [x] JazzCash client + schemas (MWALLET)
336
366
  - [ ] HBL payment gateway
337
367
  - [ ] ABL payment gateway
338
368
  - [ ] UBL payment gateway
@@ -1,61 +1,14 @@
1
- import httpx
2
1
  import pytest
3
2
 
4
3
  from src.raqm_core.exceptions.exceptions import NetworkError, PaymentError
5
4
  from src.raqm_core.easypaisa import EasyPaisa
6
-
7
- MA_SUCCESS_BODY = {
8
- "orderId": "abc123",
9
- "storeId": 43,
10
- "transactionId": "253184",
11
- "transactionDateTime": "11/08/2018 11:30 PM",
12
- "responseCode": "0000",
13
- "responseDesc": "SUCCESS",
14
- }
15
-
16
- OTC_SUCCESS_BODY = {
17
- "orderId": "abc123",
18
- "storeId": 43,
19
- "transactionDateTime": "11/08/2021 11:30 PM",
20
- "responseCode": "0000",
21
- "responseDesc": "SUCCESS",
22
- "paymentToken": "tok_abc123",
23
- "paymentTokenExpiryDateTime": "12/08/2021 11:30 PM",
24
- }
25
-
26
- INQUIRE_SUCCESS_BODY = {
27
- "orderId": "abc123",
28
- "storeId": 43,
29
- "transactionId": "253184",
30
- "transactionDateTime": "11/08/2021 11:30 PM",
31
- "responseCode": "0000",
32
- "responseDesc": "SUCCESS",
33
- "accountNum": "123456789",
34
- "storeName": "Test Store",
35
- "paymentToken": None,
36
- "transactionStatus": "COMPLETED",
37
- "transactionAmount": "1.23",
38
- "paymentTokenExpiryDateTime": None,
39
- "msisdn": "03458508726",
40
- "paymentMode": "MA",
41
- }
42
-
43
-
44
- def make_client(response_body: dict, status_code: int = 200) -> httpx.AsyncClient:
45
- def handler(request: httpx.Request) -> httpx.Response:
46
- return httpx.Response(status_code=status_code, json=response_body)
47
-
48
- return httpx.AsyncClient(transport=httpx.MockTransport(handler))
49
-
50
-
51
- def make_ep(response_body: dict) -> EasyPaisa:
52
- return EasyPaisa(
53
- store_id="43",
54
- username="admin",
55
- password="123",
56
- sandbox=True,
57
- client=make_client(response_body),
58
- )
5
+ from tests.conftest import (
6
+ INQUIRE_SUCCESS_BODY,
7
+ MA_SUCCESS_BODY,
8
+ OTC_SUCCESS_BODY,
9
+ make_client,
10
+ make_ep,
11
+ )
59
12
 
60
13
 
61
14
  class TestPayViaMA:
@@ -1,46 +1,8 @@
1
- import httpx
2
1
  import pytest
3
2
 
4
3
  from src.raqm_core.exceptions.exceptions import NetworkError, PaymentError
5
4
  from src.raqm_core.jazzcash import JazzCash
6
-
7
- MWALLET_SUCCESS_BODY = {
8
- "pp_Amount": "1000",
9
- "pp_AuthCode": "123456",
10
- "pp_BankID": "",
11
- "pp_BillReference": "bill123",
12
- "pp_Language": "EN",
13
- "pp_MerchantID": "MERCH123",
14
- "pp_ResponseCode": "000",
15
- "pp_ResponseMessage": "Success",
16
- "pp_RetreivalReferenceNo": "RET123",
17
- "pp_SubMerchantId": "SUBMERCH123",
18
- "pp_TxnCurrency": "PKR",
19
- "pp_TxnDateTime": "20260101120000",
20
- "pp_TxnRefNo": "TXN123456",
21
- "pp_SettlementExpiry": "20260101130000",
22
- "pp_TxnType": "MWALLET",
23
- "pp_Version": "1.1",
24
- "pp_SecureHash": "abc123hash",
25
- }
26
-
27
-
28
- def make_client(response_body: dict, status_code: int = 200) -> httpx.AsyncClient:
29
- def handler(request: httpx.Request) -> httpx.Response:
30
- return httpx.Response(status_code=status_code, json=response_body)
31
-
32
- return httpx.AsyncClient(transport=httpx.MockTransport(handler))
33
-
34
-
35
- def make_jc(response_body: dict) -> JazzCash:
36
- return JazzCash(
37
- merchant_id="MERCH123",
38
- sub_merchant_id="SUBMERCH123",
39
- hash_key="test_hash_key",
40
- password="test_password",
41
- sandbox=True,
42
- client=make_client(response_body),
43
- )
5
+ from tests.conftest import MWALLET_SUCCESS_BODY, make_client, make_jc
44
6
 
45
7
 
46
8
  class TestPayViaMWallet:
@@ -48,6 +10,7 @@ class TestPayViaMWallet:
48
10
  async def test_success(self):
49
11
  jc = make_jc(MWALLET_SUCCESS_BODY)
50
12
  result = await jc.pay_via_mwallet(
13
+ cnic="123456",
51
14
  mobile_number="03001234567",
52
15
  amount="1000",
53
16
  description="Test payment",
@@ -77,6 +40,7 @@ class TestPayViaMWallet:
77
40
  jc = make_jc(payload)
78
41
  with pytest.raises(PaymentError) as exc_info:
79
42
  await jc.pay_via_mwallet(
43
+ cnic="123456",
80
44
  mobile_number="03001234567",
81
45
  amount="1000",
82
46
  description="Test payment",
@@ -97,6 +61,7 @@ class TestPayViaMWallet:
97
61
  )
98
62
  with pytest.raises(NetworkError):
99
63
  await jc.pay_via_mwallet(
64
+ cnic="123456",
100
65
  mobile_number="03001234567",
101
66
  amount="1000",
102
67
  description="Test payment",
File without changes