当前位置: 首页 > 知识库问答 >
问题:

如何使一个刚性的贝宝REST API支付周期?

南门志
2023-03-14

我在我的Flask应用程序上摆弄paypalrestsdk,下面是支付的顺序。有经验的人能指出周期是否僵化吗?

>

  • 使用适当的重定向URL创建付款。

    payment = paypalrestsdk.Payment({
        "intent": "sale",
        "payer": {
            "payment_method": "paypal"
        },
        "redirect_urls": {
            "return_url": url_for('.payment_success', _external=True),
            "cancel_url": url_for('.payment_cancel', _external=True)
        },
    ...})
    if payment.create():
          ...
    

    如果成功,请在数据库中保存以下付款响应详细信息。

    class PayPalPayment(db.Model):
        __tablename__ = 'ediket_paypal_payment'
        id = db.Column(db.Integer, primary_key=True)
        user_id = db.Column(db.Integer, db.ForeignKey('ediket_ediketuser.id'))
        payment_id = db.Column(db.String(30))
        amount = db.Column(db.String(10))
        state = db.Column(db.String(10))
        redirect_url = db.Column(db.VARCHAR)
        created_at = db.Column(db.DateTime)
        updated_at = db.Column(db.DateTime)
    

    然后,使用HATEOAS链接重定向。

    从数据库中查找当前用户上一个状态为“已创建”的事务。

    pending_payment = PayPalPayment.query.filter_by(user_id=user_id).filter_by(state='created').first()
    

    使用payment_id和payer_id执行付款

    payment = paypalrestsdk.Payment.find(pending_payment.payment_id)
    if payment.execute({"payer_id": request.args.get('PayerID')}):
        #We are done!
        #Update Payment model for completion
    

    所有这些工作都很好,但是我不太确信这个流对于现实世界的应用程序是否安全。由于返回url只包含PayerID和Token,所以找到要执行的相关支付的唯一方法是使用当前用户id和status='created'对支付表进行盲查询。

    有没有改进的空间?

  • 共有1个答案

    郭永怡
    2023-03-14

    此后的任何修改都是存储了名为token的额外字段,该字段与HATEOAS链接一起传递。通过存储此令牌,我能够定位用户的未决付款,以继续执行。

    更新:

    下面是实现细节。它可能不是完美的,但它现在起到了作用。

    class PayPalPayment(db.Model):
        __tablename__ = 'paypal_payment'
        id = db.Column(db.Integer, primary_key=True)
        user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
        product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
        payment_id = db.Column(db.String(30))
        amount = db.Column(db.String(10))
        state = db.Column(db.String(10))
        token = db.Column(db.String(30))
        redirect_url = db.Column(db.Text)
        created_at = db.Column(db.DateTime)
        updated_at = db.Column(db.DateTime)
    
        def __init__(self, payment, product_id, user_id):
            self.user_id = user_id
            self.product_id = product_id
            self.payment_id = payment.id
            self.amount = payment.transactions[0].amount.total
            self.state = payment.state
    
            self.created_at = datetime.datetime.strptime(payment.create_time, "%Y-%m-%dT%H:%M:%SZ")
            self.updated_at = datetime.datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
    
            for link in payment.links:
                if link.method == "REDIRECT":
                    self.redirect_url = link.href
    
            parsed = urlparse.urlparse(self.redirect_url)
            self.token = urlparse.parse_qs(parsed.query)['token'][0]
    
    @payment_view.route('/paypal', methods=['POST'])
    @login_required
    def paypal_payment():
        user_id = current_user.get_id()
        product = Product.query.filter_by(id=request.form.get('product')).first_or_404()
        past = datetime.datetime.utcnow() - datetime.timedelta(minutes=3)
        count = PayPalPayment.query.filter_by(user_id=user_id).filter_by(state='created').filter(PayPalPayment.created_at >= past).count()
    
        # To prevent a spam where user creates Payment and never comes back to it
        if count > 4:
            return Response(render_template('payment/overflow.html'), mimetype='text/html')
    
        payment = paypalrestsdk.Payment({
            "intent": "sale",
            "payer": {
                "payment_method": "paypal"
            },
            "redirect_urls": {
                "return_url": url_for('.payment_success', _external=True),
                "cancel_url": url_for('.payment_cancel', _external=True)
            },
    
            "transactions": [{
                "amount": {
                    "total": product.amount,
                    "currency": "USD"
                },
                "description": product.description
            }]
        })
    
        if payment.create():
            new_payment = PayPalPayment(payment, product.id, user_id)
            db.session.add(new_payment)
            db.session.commit()
            return redirect(new_payment.redirect_url, code=302)
        else:
            return Response(render_template('payment/cancel.html'), mimetype='text/html')
    
    @payment_view.route('/success')
    @login_required
    def payment_success():
        user_id = current_user.get_id()
        payerID = request.args.get('PayerID', None)
        token = request.args.get('token', None)
    
        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:
            abort(404)
    
        template = 'payment/error.html'
        if payment.execute({"payer_id": request.args.get('PayerID')}):
            pending_payment.state = payment.state
            pending_payment.updated_at = datetime.datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
            template = 'payment/success.html'
    
        db.session.commit()
        return Response(render_template(template), mimetype='text/html')
    

    请随便批评。

     类似资料:
    • 我使用贝宝rest api支付资源来更新付款金额和项目信息;我只是想改变项目的价格和税收;和运费金额;但返回MALFORMED_REQUEST;让我喝醉... request_data是: 并返回:{"name":"MALFORMED_REQUEST","消息":"MALFORMED_REQUEST","information_link":"https://developer.paypal.com

    • 我创建贝宝Restapi以下步骤1.创建登录ID由developer.paypal.com2.点击我的应用程序3.点击按钮"创建应用程序"创建测试应用程序4.通过单击testapp,我得到了两个api凭据(i)测试凭据(ii)实时凭据(通过单击显示) 我的代码中存在上述api(客户端ID和密码)的问题,代码给出的错误号为401或某个时间为400 我已检查“帐户资格” PayPal付款和登录与Pay

    • 问题内容: 我有一个要添加“立即付款”按钮的产品列表,这样我就可以允许我的客户通过Paypal付款。 我已经阅读了文档,找不到如何执行此操作。我可以添加多个项目,但这不会很方便,因为我已经有要处理的项目列表。我还需要结帐流程来逐项列出订单,因此以1个价格“立即购买”也不是一件好事。 任何帮助表示赞赏的人,我都尝试过(没有运气): 问题答案: 请参阅此示例,并相应地进行更改。基本上将下划线添加到项目

    • 我对Paypal express结账有点困惑,是否有可能为通过信用卡付款而没有账单协议的买家进行参考付款(我们禁用账单协议,因为如果启用,Paypal会要求创建新帐户)。 我知道在payment Pro中,我们可以在没有任何账单协议的情况下进行参考支付,因为它仅限于少数几个我们无法使用的国家。 注意:我们的商户账户已经激活,可以进行参考支付。 谢谢,阿兹

    • 1、新版支付宝支付配置 配置支付宝支付之前,需要到支付宝商家中心开通手机网站应用和电脑网站应用两个产品。 产品开通链接:快捷手机wap支付 电脑网站支付 一个工作日即可通过审核,完成产品签约。 接下来,介绍支付宝支付配置教程。 第一步 登录商城后台,设置->交易设置->支付配置 ,选择支付宝支付,点击配置,进入到支付宝支付参数配置界面,选择新版支付宝。 需要我们配置应用APPID、应用私钥、应用公

    • 我在沙箱中工作,使用PayPal REST。net SDK方法支付。创建一个信用卡对象。当所有参数有效且使用来自的测试CC编号时https://developer.paypal.com/webapps/developer/docs/integration/direct/accept-credit-cards/,付款对象从该方法返回,一切正常。 但是,当参数无效时,例如过去的过期日期或沙箱无法识别的