繁体   English   中英

Paypal 集成到 Flask 应用程序

[英]Paypal integration to Flask application

阅读https://developer.paypal.com/docs/api/后,我对 Paypal 流事件略有误解。 我想将快速结账和信用卡付款集成到我的网站。 我正在使用Flaskpaypalrestsdk没有任何 Flask 扩展。

以下是我的应用程序的摘录:

@app.route('/', methods=['GET'])
def index():
    # Page with but form, price/quantity/name values
    # are stored in hidden fields, "Buy now" acts as submit
    return render_template('index.html')

@app.route('/payment/paypal', methods=['POST'])
def payment_paypal():
    # Here I am creating dict with required params
    payment_template = {
        'intent': 'sale',
        'payer': {'payment_method': 'paypal'},
        'redirect_urls': {
          'return_url': url_for('payment_paypal_execute'),
          'cancel_url': url_for('payment_paypal_error')
        },
        ......
    }

    payment = paypalrestsdk.Payment(payment)

    if payment.create():
        print('Payment "{}" created successfully'.format(payment.id))

        for link in payment.links:
            if link.method == "REDIRECT":
                redirect_url = str(link.href)
                print('Redirect for approval: {}'.format(redirect_url))
                return redirect(redirect_urls)

@app.route('/payment/paypal/execute', methods=['GET'])
def payment_paypal_execute():
    payer_id = request.args.get('payerId')
    payment_id = request.args.get('paymentId')
    token = request.args.get('token')

    pending_payment = PayPalPayment.query.filter_by(token=token).filter_by(state='created').first_or_404()

    try:
        payment = paypalrestsdk.Payment.find(pending_payment.payment_id)
    except paypalrestsdk.exceptions.ResourceNotFound as ex:
        print('Paypal resource not found: {}'.format(ex))
        abort(404)

    if payment.execute({"payer_id": payer_id}):
        pending_payment.state = payment.state
        pending_payment.updated_at = datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
        db.session.commit()
        return render_template('payment/success.html', payment_id=payment.id, state=payment.state)

    return render_template('payment/error.html', payment_error=payment.error, step='Finallizing payment')

它工作正常,点击按钮payment成功创建(状态created )后,用户重定向到批准页面。 在那里他单击“确认”...当我指定 return_url 时,我再也没有返回到我的应用程序,事件! 即应用程序永远不会被告知买方批准付款,它应该在我自己的数据库中更新,并且新的许可证应该发送给那个人。

问题:

  1. 我找不到使用pyhtonrestsdk定义一些回调的方法。 怎么做?

  2. 即使我使用data-callback添加回调(我尝试使用纯 Javascript 按钮代码嵌入 Express Checkout),我的应用程序也没有被调用。 我怀疑是因为远程服务器无法调用http://127.0.0.1/payment/paypal/success

  3. 用户可以在单击“确认”后立即使用 PayPal 确认关闭窗口,因此我无法相信它稍后以某种方式执行的浏览器重定向。

最后,我怀疑我不清楚 PayPal 工作流程,但我无法在开发人员门户上找到有关它的更多信息。

像往常一样,魔鬼藏在细节中。 我的主要问题如下:paypal 没有将我重定向到我的应用程序,但我发现它(在确认后)将我重定向到 URL,它看起来像https://sandbox.paypal.com/ ,查询字符串包含所需的参数。 redirect_urls按预期工作,只是将我重定向到错误的主机。

之后我想起了url_for生成相对链接。 所以刚刚添加了关键字_external=True我已经被重定向到我的应用程序,所有必需的参数和付款已成功确认和执行。

即正确的redirect_urls块将如下所示:

'redirect_urls': {
    'return_url': url_for('payment_paypal_execute', _external=True),
    'cancel_url': url_for('payment_paypal_error', _external=True)
}

最后我有以下工作流程:

  1. 打开/ ( index )有按钮Pay with PayPal是形式里面的图片按钮。 在此按钮表单旁边包含带有金额、产品名称和数量的隐藏字段(实际上这不是一个好主意,因为我们不能信任用户,所以我只存储product_license_type_id存储在数据库中并包含有关产品的所有必需信息)。

  2. 单击它后, POST表单到“/payment/paypal”(paypal_create),其中创建对象Payment并填充所有字段。 如果调用payment.create成功完成,它还会在我自己的数据库中创建记录,其中包含payment_idstate (这些字段与 paypal 工作流程相关,当然实际上我正在存储与我的应用程序相关的其他几个字段)。

  3. 在 PayPal 端创建付款后,应用程序会查看列表payment.links响应。 我们想要一个rel == 'approval_url'method == 'REDIRECT'并返回flask.redirect(found_link)

  4. 在 PayPal 网站上,买家应单击“批准”,查看送货地址,然后他将立即重定向到redirect_urls.return_url ,查询字符串中包含以下参数: PayerID , paymentId , token

  5. 一旦重定向回来,您应该从查询字符串中获取此参数(请记住 - 它区分大小写!),使用 PayPal API 查找付款( payment = paypalrestsdk.Payment.find(payment_id) )并完成它( payment.execute({"payer_id": payer_id}):

  6. 完成付款后,状态更改为approved

  7. ....

  8. 利润!

UPD :您不需要在销售帐户首选项中打开“自动重定向”,这种方法适用于将一个帐户集成到多个站点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM