MPESA C2B Validation and Confirmation Transaction Not Responding

2.1k views Asked by At

I am trying to record confirmed mpesa transactions. I am running them on the safaricom sandbox. My register url function and simulate_transaction both return success from my local terminal. However, I have hosted by app on heroku and the logs on there do not show any kind of response (I have function-based views with code to print out both transactions.)

My c2b.py:

import keys
import requests
from requests.auth import HTTPBasicAuth
# import lipanampesa

# Getting MPESA Access Token
consumer_key = keys.consumer_key
consumer_secret = keys.consumer_secret
api_URL = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials"

try:
    r = requests.get(api_URL, auth=HTTPBasicAuth(
        consumer_key, consumer_secret))
except:
    r = requests.get(api_URL, auth=HTTPBasicAuth(
        consumer_key, consumer_secret), verify=False)
print(r.json())
json_response = r.json()
my_access_token = json_response["access_token"]


def register_url():
    access_token = my_access_token  # lipanampesa.my_access_token  # my_access_token
    api_url = "https://sandbox.safaricom.co.ke/mpesa/c2b/v1/registerurl"
    headers = {"Authorization": "Bearer %s" % access_token}
    request = {"ShortCode": keys.shortcode,
               "ResponseType": "Completed",
               "ConfirmationURL": "https://sheltered-river-94769.herokuapp.com/api/payments/C2B-CONFIRMATION/",
               "ValidationURL": "https://sheltered-river-94769.herokuapp.com/api/payments/C2B-VALIDATION/",
               }

    try:
        response = requests.post(api_url, json=request, headers=headers)
    except:
        response = requests.post(
            api_url, json=request, headers=headers, verify=False)

    print(response.text)


register_url()


def simulate_c2btransaction():
    access_token = my_access_token
    api_url = "https://sandbox.safaricom.co.ke/mpesa/c2b/v1/simulate"
    headers = {"Authorization": "Bearer %s" % access_token}
    request = {"ShortCode": keys.shortcode,
               # "CustomerPayBillOnline",  # CustomerBuyGoodsOnline
               "CommandID": "CustomerPayBillOnline",
               "Amount": "50",
               # phone_number sendng the trxn, starting with Xtrycode minus plus (+) sign
               "Msisdn": keys.test_msisdn,
               "BillRefNumber": "123456789",
               }

    try:
        response = requests.post(api_url, json=request, headers=headers)

    except:
        response = requests.post(
            api_url, json=request, headers=headers, verify=False)

    print(response.text)


simulate_c2btransaction()

My urls.py:

from django.contrib import admin
from django.urls import path, include, re_path
from django.views.generic.base import TemplateView
from mpesa.api.views import LNMCallbackUrlAPIView, C2BConfirmationAPIView, C2BValidationAPIView, TestConfirmation, TestValidation
#from django.conf.urls import patterns

# NOTE:
# URLS transacting with mpesa should not have words like mpesa,
# safaricom, etc
app_name = "mpesa-api"

urlpatterns = [
    path('lnm/', LNMCallbackUrlAPIView.as_view(), name="lnm-callback"),
    path('C2B-VALIDATION/', TestValidation, name="c2b-validation"),
    path('C2B-CONFIRMATION/', TestConfirmation,
         name="c2b-confirmation"),
    # path('C2B-VALIDATION/', C2BValidationAPIView.as_view(), name="c2b-validation"),
    # path('C2B-CONFIRMATION/', C2BConfirmationAPIView.as_view(),
    #      name="c2b-confirmation"),
]

My views.py:

@csrf_exempt
def TestValidation(request):
    mpesa_body =request.body.decode('utf-8')
    print(mpesa_body, "This is request data in validation")
    context = {
        "ResultCode": 0,
        "ResultDesc": "Accepted"
    }
    return JsonResponse(dict(context))
    # return Response({"ResultCode": 0, "ResultDesc": "Accepted"})


@csrf_exempt
def TestConfirmation(request):
    mpesa_body =request.body.decode('utf-8')
    print(mpesa_body, "This is request data in confirmation")
    context = {
        "ResultCode": 0,
        "ResultDesc": "Accepted"
    }
    return JsonResponse(dict(context))
    # return Response({"ResultCode": 0,"ResultDesc": "Accepted"})

I would really appreciate any help with figuring this out. Thanks!

1

There are 1 answers

0
annexus On

Try not to use your own credentials when simulating any payment.

I was in a similar situation sometime back and I wasted a lot of time trying to figure out what could be wrong with my app.

Instead, go to api section of the developer.safaricom.co.ke site, click on the c2b api and on the right hand side card ( the black one ), choose your app and at the bottom right corner, you'll see a button comprised of three horizontal bars. Click on it to copy the test credentials and hopefully, your app will now work.