2015-12-16 14 views
8

https://developer.paypal.com/docs/api/を読んだ後に、私はPaypalフローイベントを誤解しています。エクスプレスチェックアウトとクレジットカードによる支払いを私のサイトに統合したいのですが。フラスコ拡張なしでFlaskpaypalrestsdkを使用しています。ここでFlaskアプリケーションへのPaypalインテグレーション

は私のアプリからの抜粋です:

@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') 

それは(状態createdで)正常に作成されたボタンpaymentをクリックした後、正常に動作され、承認ページにリダイレクトユーザー。そこで彼は「確認」をクリックします...私はreturn_urlを指定すると、私のアプリケーション、イベントに戻ったことはありません!私。バイヤーが支払いを承認したことをアプリケーションに通知することはできず、それは自分のデータベースで更新し、その人に新しいライセンスを送付しなければなりません。

問題:

  1. 私はpyhtonrestsdkを使用して、いくつかのコールバックを定義する方法を見つけることができません。どうやってするの?

  2. data-callbackでコールバック(純粋なJavascriptボタンコードを使用してエクスプレスチェックアウトを埋め込みました)を追加しても、私のアプリケーションは呼び出されませんでした。私はリモートサーバーが電話できなかったので疑う。http://127.0.0.1/payment/paypal/success

  3. ユーザーは「確認」をクリックした直後にウィンドウを閉じることができたので、後で何らかの形で実行したブラウザリダイレクトを信頼できなかった。

最後に、私はPayPalワークフローを明確に理解していないと思うが、開発者ポータルでこのイベントに関する詳細情報を見つけることができなかった。

+0

リダイレクトしようとすると奇妙なCORSエラーが発生します。 "paypal.sandbox.comを読み込むことができません 'Access-Control-Allow-Origin'ヘッダーが要求されたリソースに存在しません。 – shell

答えて

2

いつものように、悪魔は詳細に隠れています。私の主な問題は次のとおりです:paypalは私のアプリケーションに私をリダイレクトしませんでしたが、質問文字列に希望のパラメータが含まれているようなhttps://sandbox.paypal.com/のようなURLに(確認後)リダイレクトされていました。私。 redirect_urlsは期待通りに機能し、間違ったホストにリダイレクトされます。

その後、私はurl_for相対のリンクを生成することを思い出しました。だからちょうど追加されたキーワード_external=True私はすべての必要な議論と私のアプリケーションにリダイレクトされ、支払いが正常に確認され、実行されました。

I.e.正しいredirect_urlsブロック意志は次のようになります。

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

は最後に、私は、ワークフロー、次の持っている:

ボタン Pay with PayPalを持って /index)を開設
  1. それは、フォーム内の画像のボタンです。このボタンフォームの横に金額、商品名、数量の隠しフィールドが含まれています(私たちはユーザーに信頼できないので、実際には良い考えではないので、DBに格納されたproduct_license_type_idのみを格納しています。

  2. フォームを '/ payment/paypal'(paypal_create)に作成すると、すべてのフィールドが塗りつぶされてPaymentになります。電話payment.createが正常に終了した場合は、私自身のデータベースにpayment_idstateのレコードを作成します(これらのフィールドはpaypalワークフローに関連しています。もちろん、私のアプリに関連する他のフィールドもいくつか保存しています)。

  3. PayPal側で支払いが作成されると、アプリケーションはリストpayment.linksの応答を探します。 tokenPayerIDpaymentId:私たちはrel == 'approval_url'と1とmethod == 'REDIRECT'をしたいとPayPalサイトの買い手でflask.redirect(found_link)

  4. を返す「承認」をクリックする必要があり、審査の配送先住所、その後、彼はすぐにクエリ文字列に次のパラメータを使用してredirect_urls.return_urlにリダイレクトされます。

  5. 一度リダイレクトされると、クエリ文字列からこのパラメータを取得する必要があります(大文字と小文字が区別されます)、PayPal API(payment = paypalrestsdk.Payment.find(payment_id))を使用して支払いを見つけて確定します(payment.execute({"payer_id": payer_id}):)。

  6. 最終決済のステータスがapprovedに変更された場合。

  7. ....

  8. 利益!

UPD:あなたは複数のサイトへのアカウントを統合するのに適したアカウントの設定と、このアプローチを販売するには、「AutoRedirect」をオンにする必要はありません。

+0

2番目のコメントを残して申し訳ありませんが、手順3でリダイレクトしようとすると「paypal.sandbox.comを読み込めません」というアクセス権が許可されていません。 – shell

関連する問題