Запуск функции Python внутри скрипта напрямую по сравнению с контроллером приложения Flask

Мне трудно понять следующее поведение.

Я интегрирую определенный API для мобильных платежей. После запуска функции оплаты вызывается API оплаты, и он, в свою очередь, должен вернуть ответ, подтверждающий получение запроса, и вскоре после запуска экрана STKPush на мобильном телефоне пользователя (API предлагается телекоммуникационной компанией, которая занимается мобильными платежами.). Сначала я написал простые скрипты Python для проверки интеграции, и они хорошо работают. Ниже приведен фрагмент того, как я запускаю его в скрипте:

def get_oauth_token():
    resource_url = "https://xxxxxxxxxxx.co.ke/oauth/v1/generate?grant_type=client_credentials"
    key = "#################"
    secret = "################"
    r = requests.get(resource_url, auth=HTTPBasicAuth(key, secret))
    return r.json()['access_token']


def lipa_online(token):
    time = str(datetime.datetime.now()).split(".")[0].replace("-", "").replace(" ", "").replace(":", "")
    password = "{0}{1}{2}".format("174379", "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919", time)
    encoded = base64.b64encode(password)
    payload = {
      "BusinessShortCode": XXXXXX,
      "Password": encoded,
      "Timestamp": time,
      "TransactionType": "PayOnline",
      "Amount": 1,
      "PartyA": 25470000000,
      "PartyB": XXXXXX,
      "PhoneNumber": 25470000000,
      "CallBackURL": "https://97ff8c8c.ngrok.io/callback",
      "AccountReference": "13dbd6hg",
      "TransactionDesc": "Just a trial"
    }
    headers = {'Authorization': 'Bearer {0}'.format(token), 'Content-Type': "application/json"}
    r = requests.post("https://xxxxxxxx.co.ke/pay/stkpush/v1/processrequest", headers=headers, json=payload)
    print r.json()

if __name__ == "__main__":
    token = get_oauth_token()
    #The line below fires the payment action.
    request_id = pay_online(token)

Запуск скрипта напрямую возвращает соответствующий ответ от API оплаты:

{u'CustomerMessage': u'Success. Request accepted for processing', u'CheckoutRequestID': u'ws_CO_07112017182534915', u'ResponseDescription': u'Success. Request accepted for processing', u'MerchantRequestID': u'8955-555026-1', u'ResponseCode': u'0'}

и запускает действие STKpush на телефоне пользователя (выполняется через API оплаты.).

Однако при выполнении той же логики, что и в контроллере веб-приложения Flask, удается вернуть соответствующий ответ, но действие STKPush никогда не запускается. Я попытался запустить его, поскольку асинхронная задача - это Celery, но я все еще получаю то же самое.

@celery.task
def lipa(token, payload):
    headers = {'Authorization': 'Bearer {0}'.format(token), 'Content-Type': "application/json"}
    saf_url = "https://xxxxxxxxxx.co.ke/pay/stkpush/v1/processrequest"
    r = requests.post(saf_url, headers=headers, json=payload)
    print r.json()


@api.route('/payment/pay/', methods=['POST'])
def make_payment():
    if not 'Authorization' in request.headers:
        abort(401)
    _data = request.headers['Authorization'].encode('ascii', 'ignore')
    token = str.replace(str(_data), 'Bearer ', '')
    if token == application.config['PAYMENT_API_KEY']:
        pass
    else:
        return jsonify({"error": "Invalid authentication token."})

    time = str(datetime.datetime.now()).split(".")[0].replace("-", "").replace(" ", "").replace(":", "")
    password = "{0}{1}{2}".format(str(application.config.get('SHORTCODE')), application.config.get('PASSCODE'), time)
    encoded = base64.b64encode(password)
    data = request.get_json(force=True)
    try:
        if data["sandbox"] == "true":
            amount = 1
        else:
            amount = data.get('amount')
    except KeyError:
        amount = data.get('amount')
    callback_url = "{0}/api/payment/mpesa/callback".format(application.config.get('SITE'))
    payload = {
        "BusinessShortCode": application.config.get('SHORTCODE'),
        "Password": encoded,
        "Timestamp": time,
        "TransactionType": "PayOnline",
        "Amount": amount,
        "PartyA": data.get('phone_number'),
        "PartyB": application.config.get('SHORTCODE'),
        "PhoneNumber": data.get('phone_number'),
        "CallBackURL": callback_url,
        "AccountReference": str(uuid.uuid4()),
        "TransactionDesc": data.get('description')
    }
    token = str(get_oauth_token())
    task = lipa.apply_async(args=[token, payload])
    return Response()

Что может быть причиной этой разницы в поведении?

Заранее спасибо.

1 ответ

Оказывается, API возвращал ошибку, которая не была обработана. Теперь все работает хорошо.

Другие вопросы по тегам