PayPal支付-Reaact框架

JoneOnenine發表於2022-01-20

前情提要

之前用React框架做過一個網站的開發,客戶是國外的公司,所以為迎合受眾,支付模組新增了我國不常用但國外常用的Paypal。最近在整理文件,就把當時寫的這篇經驗總結再整合以下發布。

paypal開發者api文件源地址

總結

  • 簡單做一個開發準備總結:

  申請一個PayPal商家賬號。

  使用賬號登入paypal,找到`sandbox`,可以看到預設的app和建立。

  可以建立一個用於本專案的app,獲取`client_id`。至此,基本就可以開始著手開發了。

官方配置地址

  • 配置。

  由於裝了react-paypal-js,以下總結全是基於此依賴的配置及使用。

  在我們的支付賬單頁面,從依賴中引入PayPalScriptProvider,以標籤的形式使用。標籤的options屬性,就是我們進行配置的位置。例項為:

import { PayPalScriptProvider } from "@paypal/react-paypal-js"
export default function PayPalPaymentElement() {
  return (
    <PayPalScriptProvider options={{ 
      "client_id": "開發準備中在sandbox拿到的client_id或者後端傳過來的"
      "currency": "收取的貨幣,如果不設定預設為USD"
    }}>
    /**這裡為PayPalButtons載入的位置,PayPalButtons只能在此環境中執行*/
    </PayPalScriptProvider>
  )
}

  注意:options屬性,client_id是必須的。專案上線前將此換為真實商家賬戶client_id。

    如果貨幣不是美元,必須為其新增`currency`並指定幣種。

官方javascript-sdk配置地址

  • PayPalButtons

    paypal.Buttons,實現點選開啟paypal支付頁面,以及整合支付。

    官方paypal.Buttons地址

    paypal-react-js提供了PayPalButtons快速整合。

    PayPalButtons地址

    關於PayPalButtons的樣式等可參考官方地址根據需求修改。說一下幾個常用屬性。

    1.createOrder

    建立paypal支付訂單時的方法,常用於支付整合。包括地址、總價等訂單詳情。


 

const createOrder = (data: any, actions: any) => {

 

return actions.order.create({
    purchasee_units: [{
      amount: {
        value: 12,//總價金額
        currency_code: "USD",//貨幣
        breakdown: {
          item_total: {...},//商品總價
          shipping: {...},//運費
          discount: {...},//折扣
        },
        shipping: {
          name: {
            full_name: "John Doe",//只支援full_name
          },
          type: "SHIPPING",//郵寄方式,可選值還有"PICKUP_IN_PERSON"
          address: {...}//地址
        }
      }
    }],
    application_context: {
      brand_name: "Sale",//品牌名
      shipping_prefrence: "SET_PROVIDED_ADDRESS",//位址列顯示
    },
    payer: {...},//消費者資訊
  }).then((orderID: any) => {});
};

<PayPalButtons 
  style={{
    layout: "horizontal",
    shape: "rect",
  }}
  createOrder={createOrder}
/>

  `action.order.create({})`有四個options分別為`intent`、`payer`、`purchase_units`、`application_context`, createOrder官方文件地址

  注1:purchase_unit物件定義1 、purchase_unit物件定義2

  注2:application_context物件定義,實際開發中,這個物件的`brand_name`以及`shipping_perfrence`都是使用頻率較高的。

  當有這樣一個需求:配送地址由使用者在網站上選擇,paypal上僅展示地址不可更改,這時`shipping_perfence`是最好的實現方式(至少在我做的這個專案時是如此),要完成這個需求,我們僅需要進行以下整合:

application_context: {
shipping_prefrence: "SET_PROVIDED_ADDRESS"//由網站提供,使用者可檢視但無法更改
//"NO_SHIPPING": 一般用於售賣的數字等無實物產品,支付頁面不顯示位址列
//"GET_FROM_FILE": 來源於使用者在當前支付頁面位址列選中的地址
}

  注3:payer物件定義

2.onApprove

  當訂單確認之後的回撥

const onApprove = (data: any, actions: any) => {
  return actions.order.capture().then(funtions (details: any) {})
}

<PayPalButtons 
  style={{
    layout: "horizontal",
    shape: "rect",
  }}
  createOrder={createOrder}
  onApprove={onApprove}
/>

  onApprove官方地址

 

3.onCancel

  當關閉paypal支付頁面,取消支付時的回撥

const onCancel = (data: any) => {}

<PayPalButtons 
  style={{
    layout: "horizontal",
    shape: "rect",
  }}
  createOrder={createOrder}
  onCancel={onCancel}
/>

  onCancel官方地址

 

4.onError

  當執行出錯時的回撥

const onError = (err: any) => {}

<PayPalButtons 
  style={{
    layout: "horizontal",
    shape: "rect",
  }}
  createOrder={createOrder}
  onError={onError}
/>

  onError官方地址

5.其他...

關於使用PayPalButtons踩過的坑(或者說因缺乏經驗而走的彎路),在這裡單獨列出來

問題描述:

  在支付頁面,點選以西paypal支付按鈕,再取消支付。

  在頁面不重新整理、路由不跳轉的前提下更改商品數量(或者郵寄方式/地址,目的為與上次點選的支付詳情區別開)。

  點選paypal支付按鈕,此時paypal支付金額/地址與上一次點選的沒有區別,也就是說訂單詳情沒有更新。

檢索問題&解決:

  一開始發現這個問題,第一反應是元件沒有從新渲染,或者資料沒有動態更新。順著這個思路開始測試,結果發現元件及資料都有更新。啊這...

  會不會是PayPal的問題?發現有`onInit/onClick`方法,藉助這個方法測試一下每次點選的時候列印傳入的資料。結果居然每次點選的時候傳入的資料都沒有更新!!!我不理解啊元件和資料都更新了,為什麼傳入的資料沒更新????

  會不會PayPalButtons沒有重渲?在官方文件找了半天只找到一個render方法,但是我用sdk根本不用自己手寫這個方法啊喂!!!

  嘗試換一個文件在react-paypal-js裡看看,可惡,居然一進來就看到一個`forceReRender`

  文件源地址 看看描述:用於重新重新渲染元件。當更改這個prop時,會銷燬當前按鈕並且以當前props的值重渲!!!這不就正是我要找的嗎!用起來

<PayPalButtons 
  style={{
    layout: "horizontal",
    shape: "rect",
  }}
  createOrder={createOrder}
  forceReRender={[
    totalprice,
    shippingAddress,
    shippingPrice,
    ...
  ]}
  />

  再執行一次剛剛發現問題的步驟,問題解決!!

  果然,用什麼東西就應該先看什麼文件。

  總結來說,這個問題出現的原因是:支付頁面不是分步執行,即沒有一步一更新,這導致資料更新時,PayPalButtons未重渲。不清楚使用原生方法編寫有沒有這個問題,畢竟官方好像只有render方法(或者有別的只是我沒找到),之後可以實踐或者關注社群看看...

相關文章