@@ -89,3 +89,258 @@ def test_c2b_service_instance(client):
8989def test_ratiba_service_instance (client ):
9090 """Test that the ratiba service is an instance of RatibaService."""
9191 assert isinstance (client .ratiba , RatibaService )
92+
93+
94+ # Tests for callback processing methods
95+ class TestCallbackProcessing :
96+ """Tests for MpesaClient callback processing methods."""
97+
98+ def test_process_stk_callback (self , client ):
99+ """Test processing STK Push callback payload."""
100+ payload = {
101+ "Body" : {
102+ "stkCallback" : {
103+ "MerchantRequestID" : "29115-34620561-1" ,
104+ "CheckoutRequestID" : "ws_CO_191220191020363925" ,
105+ "ResultCode" : 0 ,
106+ "ResultDesc" : "The service request is processed successfully." ,
107+ "CallbackMetadata" : {
108+ "Item" : [
109+ {"Name" : "Amount" , "Value" : 1.0 },
110+ {"Name" : "MpesaReceiptNumber" , "Value" : "LHG31AA5TX" },
111+ {"Name" : "Balance" },
112+ {"Name" : "TransactionDate" , "Value" : 20191219102115 },
113+ {"Name" : "PhoneNumber" , "Value" : 254712345678 },
114+ ]
115+ },
116+ }
117+ }
118+ }
119+ result = client .process_stk_callback (payload )
120+ assert result .Body .stkCallback .MerchantRequestID == "29115-34620561-1"
121+ assert result .Body .stkCallback .ResultCode == 0
122+ assert result .amount == 1.0
123+ assert result .mpesa_receipt_number == "LHG31AA5TX"
124+
125+ def test_process_stk_query_callback (self , client ):
126+ """Test processing STK Push query callback payload."""
127+ payload = {
128+ "MerchantRequestID" : "12345" ,
129+ "CheckoutRequestID" : "ws_CO_260520211133524545" ,
130+ "ResponseCode" : 0 ,
131+ "ResponseDescription" : "Success" ,
132+ "ResultCode" : 0 ,
133+ "ResultDesc" : "The service request is processed successfully." ,
134+ }
135+ result = client .process_stk_query_callback (payload )
136+ assert result .ResultCode == 0
137+ assert result .MerchantRequestID == "12345"
138+
139+ def test_process_account_balance_callback (self , client ):
140+ """Test processing account balance callback payload."""
141+ payload = {
142+ "Result" : {
143+ "ResultType" : 0 ,
144+ "ResultCode" : 0 ,
145+ "ResultDesc" : "The service request has been processed successfully." ,
146+ "OriginatorConversationID" : "10571-774651-1" ,
147+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
148+ "TransactionID" : "LHG31AA5TX" ,
149+ "ResultParameters" : {
150+ "ResultParameter" : [
151+ {
152+ "Key" : "AccountBalance" ,
153+ "Value" : "580000.00" ,
154+ }
155+ ]
156+ },
157+ "ReferenceData" : {
158+ "ReferenceItem" : {
159+ "Key" : "QueueOfficeNumber" ,
160+ "Value" : "00000" ,
161+ }
162+ },
163+ }
164+ }
165+ result = client .process_account_balance_callback (payload )
166+ assert result .Result .ResultCode == 0
167+ assert result .Result .ConversationID == "AN41320161328197f28cc1d183985ef4f1"
168+
169+ def test_process_account_balance_timeout (self , client ):
170+ """Test processing account balance timeout callback payload."""
171+ payload = {
172+ "Result" : {
173+ "ResultType" : 0 ,
174+ "ResultCode" : 2001 ,
175+ "ResultDesc" : "The service request has timed out." ,
176+ "OriginatorConversationID" : "10571-774651-1" ,
177+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
178+ "TransactionID" : "LHG31AA5TX" ,
179+ }
180+ }
181+ result = client .process_account_balance_timeout (payload )
182+ assert result .Result .ResultCode == 2001
183+ assert "timed out" in result .Result .ResultDesc
184+
185+ def test_process_b2c_callback (self , client ):
186+ """Test processing B2C callback payload."""
187+ payload = {
188+ "Result" : {
189+ "ResultType" : 0 ,
190+ "ResultCode" : 0 ,
191+ "ResultDesc" : "The service request has been processed successfully." ,
192+ "OriginatorConversationID" : "10571-774651-1" ,
193+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
194+ "TransactionID" : "LHG31AA5TX" ,
195+ "ResultParameters" : [
196+ {"Key" : "TransactionAmount" , "Value" : "100.00" },
197+ {"Key" : "TransactionReceipt" , "Value" : "LHG31AA5TX" },
198+ {"Key" : "B2CRecipientIsLocked" , "Value" : "false" },
199+ {"Key" : "B2CChargesPaidAccountAvailableFunds" , "Value" : "49900.00" },
200+ {"Key" : "B2CUtilityAccountAvailableFunds" , "Value" : "199900.00" },
201+ {"Key" : "TransactionCompletedDateTime" , "Value" : "31.12.2021 23:59:59" },
202+ {"Key" : "B2CRecipientPhoneNumber" , "Value" : "254712345678" },
203+ ],
204+
205+ }
206+ }
207+ result = client .process_b2c_callback (payload )
208+ assert result .Result .ResultCode == 0
209+ assert result .Result .ConversationID == "AN41320161328197f28cc1d183985ef4f1"
210+
211+ def test_process_b2b_callback (self , client ):
212+ """Test processing B2B callback payload."""
213+ payload = {
214+ "resultCode" : "0" ,
215+ "resultDesc" : "The service request is processed successfully." ,
216+ "amount" : "71.0" ,
217+ "requestId" : "404e1aec-19e0-4ce3-973d-bd92e94c8021" ,
218+ "resultType" : "0" ,
219+ "conversationID" : "AG_20230426_2010434680d9f5a73766" ,
220+ "transactionId" : "RDQ01NFT1Q" ,
221+ "status" : "SUCCESS" ,
222+ }
223+ result = client .process_b2b_callback (payload )
224+ assert result .conversationID == "AG_20230426_2010434680d9f5a73766"
225+ assert result .resultCode == "0"
226+
227+ def test_process_transactions_callback (self , client ):
228+ """Test processing transaction status callback payload."""
229+ payload = {
230+ "Result" : {
231+ "ResultType" : 0 ,
232+ "ResultCode" : 0 ,
233+ "ResultDesc" : "The service request has been processed successfully." ,
234+ "OriginatorConversationID" : "10571-774651-1" ,
235+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
236+ "TransactionID" : "LHG31AA5TX" ,
237+ "ResultParameters" : [
238+ {"Key" : "TransactionAmount" , "Value" : "100.00" },
239+ {"Key" : "TransactionStatus" , "Value" : "Completed" },
240+ {"Key" : "TransactionDate" , "Value" : "31.12.2021 23:59:59" },
241+ {"Key" : "ReceiptNo" , "Value" : "LHG31AA5TX" },
242+ ],
243+
244+ }
245+ }
246+ result = client .process_transactions_callback (payload )
247+ assert result .Result .ResultCode == 0
248+ assert result .Result .ConversationID == "AN41320161328197f28cc1d183985ef4f1"
249+
250+ def test_process_bill_manager_callback (self , client ):
251+ """Test processing bill manager callback payload."""
252+ payload = {
253+ "transactionId" : "RJB53MYR1N" ,
254+ "paidAmount" : 5000 ,
255+ "msisdn" : "254722000000" ,
256+ "dateCreated" : "2021-10-01" ,
257+ "accountReference" : "BC001" ,
258+ "shortCode" : 456545 ,
259+ }
260+ result = client .process_bill_manager_callback (payload )
261+ assert result .msisdn == "254722000000"
262+ assert result .paidAmount == 5000
263+
264+ def test_process_tax_remittance_callback (self , client ):
265+ """Test processing tax remittance callback payload."""
266+ payload = {
267+ "Result" : {
268+ "ResultType" : 0 ,
269+ "ResultCode" : 0 ,
270+ "ResultDesc" : "The service request has been processed successfully." ,
271+ "OriginatorConversationID" : "10571-774651-1" ,
272+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
273+ "TransactionID" : "LHG31AA5TX" ,
274+ "ResultParameters" : {
275+ "ResultParameter" : [
276+ {"Key" : "TransactionAmount" , "Value" : "100.00" },
277+ {"Key" : "TransactionReceipt" , "Value" : "LHG31AA5TX" },
278+ {"Key" : "TransactionDate" , "Value" : "31.12.2021 23:59:59" },
279+ ]
280+ },
281+ }
282+ }
283+ result = client .process_tax_remittance_callback (payload )
284+ assert result .Result .ResultCode == 0
285+ assert result .Result .ConversationID == "AN41320161328197f28cc1d183985ef4f1"
286+
287+ def test_process_dynamic_qr_code_callback (self , client ):
288+ """Test processing dynamic QR code callback payload."""
289+ payload = {
290+ "ResponseCode" : "00000000" ,
291+ "ResponseDescription" : "success" ,
292+ "QRCode" : "00000101010101010101" ,
293+ }
294+ result = client .process_dynamic_qr_code_callback (payload )
295+ assert result .ResponseCode == "00000000"
296+ assert result .ResponseDescription == "success"
297+
298+ def test_process_ratiba_service_callback (self , client ):
299+ """Test processing ratiba service callback payload."""
300+ payload = {
301+ "ResponseHeader" : {
302+ "responseRefID" : "0acc0239-20fa-4a52-8b9d-9bd64c0465c3" ,
303+ "requestRefID" : "0acc0239-20fa-4a52-8b9d-9bd64c0465c3" ,
304+ "responseCode" : "0" ,
305+ "responseDescription" : "The service request is processed successfully" ,
306+ },
307+ "ResponseBody" : {
308+ "ResponseData" : [
309+ {"Name" : "TransactionID" , "Value" : "SC8F2IQMH5" },
310+ {"Name" : "responseCode" , "Value" : "0" },
311+ {"Name" : "Status" , "Value" : "OKAY" },
312+ {"Name" : "Msisdn" , "Value" : "254******867" },
313+ ]
314+ },
315+ }
316+
317+ result = client .process_ratiba_service_callback (payload )
318+ assert result .ResponseHeader .requestRefID == "0acc0239-20fa-4a52-8b9d-9bd64c0465c3"
319+ assert any (
320+ item .Name == "TransactionID" and item .Value == "SC8F2IQMH5"
321+ for item in result .ResponseBody .ResponseData
322+ )
323+
324+
325+ def test_process_reversal_callback (self , client ):
326+ """Test processing reversal callback payload."""
327+ payload = {
328+ "Result" : {
329+ "ResultType" : 0 ,
330+ "ResultCode" : "21" ,
331+ "ResultDesc" : "The service request has been processed successfully." ,
332+ "OriginatorConversationID" : "10571-774651-1" ,
333+ "ConversationID" : "AN41320161328197f28cc1d183985ef4f1" ,
334+ "TransactionID" : "LHG31AA5TX" ,
335+ "ResultParameters" : {
336+ "ResultParameter" : [
337+ {"Key" : "TransactionAmount" , "Value" : "100.00" },
338+ {"Key" : "TransactionReceipt" , "Value" : "LHG31AA5TX" },
339+ {"Key" : "TransactionDate" , "Value" : "31.12.2021 23:59:59" },
340+ ]
341+ },
342+ }
343+ }
344+ result = client .process_reversal_callback (payload )
345+ assert result .Result .ResultCode == '21'
346+ assert result .Result .ConversationID == "AN41320161328197f28cc1d183985ef4f1"
0 commit comments