PayPal支付-Reaact框架
前情提要
之前用React框架做过一个网站的开发,客户是国外的公司,所以为迎合受众,支付模块添加了我国不常用但国外常用的Paypal。最近在整理文档,就把当时写的这篇经验总结再整合以下发布。
总结
- 简单做一个开发准备总结:
申请一个PayPal商家账号。
使用账号登录paypal,找到`sandbox`,可以看到默认的app和创建。
可以创建一个用于本项目的app,获取`client_id`。至此,基本就可以开始着手开发了。
-
依赖。
项目使用的是React框架开发,在项目中安装了`
react-paypal-js`
sdk
- 配置。
由于装了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`并指定币种。
-
PayPalButtons
paypal.Buttons,实现点击打开paypal支付页面,以及集成支付。
在
paypal-react-js
提供了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} />
3.onCancel
当关闭paypal支付页面,取消支付时的回调
const onCancel = (data: any) => {} <PayPalButtons style={{ layout: "horizontal", shape: "rect", }} createOrder={createOrder} onCancel={onCancel} />
4.onError
当执行出错时的回调
const onError = (err: any) => {} <PayPalButtons style={{ layout: "horizontal", shape: "rect", }} createOrder={createOrder} 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方法(或者有别的只是我没找到),之后可以实践或者关注社区看看...