gathuku / laravel_mpesa

A simple mpesa package for laravel framework | https://beyode.co.ke/mpesa
MIT License
48 stars 53 forks source link

Error: System internal error when running b2c #21

Closed timgithinji closed 3 years ago

timgithinji commented 3 years ago

I have the following in my mpesa.php config file

 /*-----------------------------------------
    |B2C timeout url
    |------------------------------------------
    */
    'b2c_timeout' => 'https://f830cde94bcd.ngrok.io/api/validate',

    /*-----------------------------------------
    |B2C results url
    |------------------------------------------
    */
    'b2c_result' => 'https://f830cde94bcd.ngrok.io/api/validate'

and in my routes api.php file I'm defining the /validate route as follows:

Route::post('mpesa/b2c', 'Payments\MpesaController@mpesaB2C');
Route::post('validate', function (Request $request) {
    \Log::info($request->getContent());
});

and in the MpesaController I'm running the b2c code in your documentation as follows:

public function mpesaB2c()
    {
        $b2cResponse=Mpesa::b2c(100, '254702067561', 'PromotionPayment', 'testing');

        dd(json_decode($b2cResponse));
    }

but when I run it the response I get is the following error:

{#415
  +"requestId": "30937-36662169-1"
  +"errorCode": "500.002.1001"
  +"errorMessage": "System internal error."
}

Is a part of my configuration wrong or are my urls wrong. I don't understand what's wrong and the error is not explanatory enough. Thanks.

gathuku commented 3 years ago

@timgithinji this is an internal error on mpesa side, keep trying

timgithinji commented 3 years ago

Okay, thanks.

OwinoBen commented 3 years ago

{ "requestId":"33908-14618724-1", "errorCode": "500.002.1001", "errorMessage": "Service is currently under maintenance. Please try again later" }

what could be the problem.. try to use daraja api

ken-nah commented 3 years ago

@OwinoBen that is most likely daraja's API temporary downtime. Happens often, take this into account when doing the integration

OwinoBen commented 3 years ago

@ken-nah thanks

OwinoBen commented 3 years ago

@csrf_exempt @require_http_methods(["POST", "GET"]) def lipa_na_mpesa(request): try: payment = Mpesa_Payments() req = json.loads(request.body.decode("utf-8")) payment.MerchantRequestID = req['Body']['stkCallback']['MerchantRequestID'] payment.CheckoutRequestID = req['Body']['stkCallback']['CheckoutRequestID'] payment.Amount = req['Body']['stkCallback']['CallbackMetadata']['Item'][0]['Value'] payment.MpesaReceiptNumber = req['Body']['stkCallback']['CallbackMetadata']['Item'][1]['Value'] payment.TransactionDate = req['Body']['stkCallback']['CallbackMetadata']['Item'][3]['Value'] payment.PhoneNumber = req['Body']['stkCallback']['CallbackMetadata']['Item'][4]['Value'] payment.save()

    order = Order.objects.get(user=request.user, ordered=False)
    orderitems = order.cart.all()
    orderitems.update(ordered=True)
    for item in orderitems:
        item.save()
    order.ordered = True
    order.payment = payment
    order.save()

except:
    pass

return JsonResponse({})

hello guys. i have a problem with saving the order objecs in the database.. what could be the problem.. this is my mpesa callbackURL function

gathuku commented 3 years ago

@OwinoBen are you getting the callback and able to save the payment object?

OwinoBen commented 3 years ago

@gathuku yes.. problem comes when i want to pass the payment on the order table

gathuku commented 3 years ago

is this python? am not familiar with the language but if you are able to save the payment you can debug to check what's happening.

OwinoBen commented 3 years ago

yeah its python.. okay thanks

gathuku commented 3 years ago

I don't know how you are getting the order since the callback isn't authenticated and you don't have access to the user. Maybe you can save save CheckoutRequestID at the request initiation stage because here you will have access to the user initiation of the request. Then after receiving the call back match the returned CheckoutRequestID in req['Body']['stkCallback']['CheckoutRequestID'] with the the already saved checkouts. The saved checkouts could also be associated with a certain order.

Sample pseudo code

checkout = OrderCheckout.find_by(checkout_request_id , req['Body']['stkCallback']['CheckoutRequestID'] )
order = checkout.order 
order.payment = payment 
order.save
OwinoBen commented 3 years ago

@gathuku sorry how do i authenticate the callback?

gathuku commented 3 years ago

I don't think you can authenticate a callback, the only thing you can check is if it's coming from the trusted source by checking the request origin IPS

OwinoBen commented 3 years ago

@gathuku good.. let me give it a try bro