操作流程来了!LZ自己是个纯后端程序员,前端的东西完全没经验,整个流程略微有点繁琐,有经验的家人们看看能不能优化一下操作简单一点。
前提条件
- 需要使用Requestly desktop version,Mac和Windows应该都行,LZ在Windows上操作的
- 操作的时候是在Requestly上launch一个新的Chrome session,用proxy模式,然后登录PayPal。这样才能在之后修改HTML response。
背景原理
PPBP里面的每一个biller在加上之后,第一次尝试付款的时候,会有一个一次性的token approve的GET请求,URL类似下面这种 (ba_token是每次都不一样)。在正常情况下,这个请求返回的HTML网页里面的Javascrip里面会包括一段关于biller和可以支持的支付方式的JSON数据,这样页面就会被导入到确认付款方式的页面 (如下图这种,以Comcast为例),确认后就可以成功发起支付。以后再尝试付款的时候,就不用再进入这个确认付款方式的页面了,可以直接进入到选卡付钱的页面。
https://www.paypal.com/agreements/approve?ba_token=BA-972990117H404421W
关于King County这个Biller的问题
现在King County这个biller的问题在于,token approve的那个请求返回的HTML网页里面,biller和可以支持的支付方式的JSON这一部分变成了如下的error json:
"billingNodeServData":{"data":{"billingAgreementContext":null},"errors":[{"message":"Cannot read properties of undefined (reading 'country_code')","path":["billingAgreementContext"],"name":"TypeError","data":{},"contingency":{},"statusCode":500}]}
而正常biller的token approve的response里面的 billingNodeServData 里面则包含了上文提到的关于biller和可以支持的支付方式的JSON数据。
操作思路
通过观察正常token approve的response里面的 billingNodeServData,发现里面的数据大部分都是静态的 (或者说是可以提前获取然后写死进去的),只有两个数据例外:
- biller信息 (
billingNodeServData.data.billingAgreementContext.merchant): 对King County来说是固定的,可以写死 - 可以支持的支付方式信息 (
billingNodeServData.data.billingAgreementContext.fundingOptionsDetails): 这部分跟每个人的账户里面的卡直接相关,可以在加一个正常的biller的时候 (比如上图中的Comcast),通过Requestly看到对应的token approve的response,然后把这部分挖出来。所以依然可以写死 - 唯二动态的数据是
billingAgreementId和billingAgreementToken这两个JSON field的数值 (都在billingNodeServData.data.billingAgreementContext里面) 是跟当前的token approve请求相关的:billingAgreementId是个类似EC-xxxxxxx的字符串,数值跟token approve的response里面搜索ecToken得到的数值一样billingAgreementToken就是token approve请求的URL里面的ba_token那个token
于是就有了如下思路:先走一边付款流程,通过requestly找到当前session下的billingAgreementId 和 billingAgreementToken,然后通过修改这个token approve HTTP的response,把提前准备好的 billingNodeServData 替换原有的,这样就能让PayPal继续走这个付款流程。
具体操作流程
-
选一个正常的接受credit card支付的biller (比如Comcast, PSE),新加上并走一次支付流程,当走到确认付款方式那个页面的时候 (图片见以上背景原理章节),去Requestly的Network Traffic页面找到这个token approve request的response,这个response HTML很大,最好复制出来到个文本编辑器上看,搜
billingNodeServData,把这一整个JSON object都保存下来,作为后续修改的蓝本。 -
把上面获得的
billingNodeServDataJSON里面的data.billingAgreementContext.merchant替换成如下的JSON object:"merchant": { "__typename": "Merchant", "billPayIntegratorName": "King County", "category": null, "country": "US", "email": null, "logo": { "__typename": "GenericURL", "href": "" }, "merchantId": "H2N3LD2J8ZBHG", "name": "King County" }, -
走一遍King County这个biller的正常付款流程,当出现
Thing does not appear to work的页面的时候,去Requestly的Network Traffic页面找到这个token approve request的response,这个response HTML很大,最好复制出来到个文本编辑器上看,搜ecToken,获得当前session的billingAgreementId。当然billingAgreementToken也获得了,就是URL里面的ba_token。然后把上一步获得的billingNodeServDataJSON里面的billingAgreementId和billingAgreementToken都替换。 -
这个时候,我们就获得了一个魔改完成后的
billingNodeServData,下一步就是写一个Requestly的modiy response body的rule来动态替换了! -
在Requestly里面右键点击 token approve那一个HTTP request,选择
Modify Response Body,开始创建如下的rule:
URL类似https://www.paypal.com/agreements/approve?ba_token=BA-972990117H404421W(用当前的ba_token)。Response Body那里选 Dynamic,然后里面就一行return response.replaceAll("<原billingNodeServData>", “<魔改的billingNodeServData>")。最后记得保存Rule。这一步的细节看下面帖子的图文补充说明:
华盛顿州king county的房产税能信用卡支付吗? - #329,来自 ryd994 -
确保Rule是enabled,然后回到PayPal那个
Thing does not appear to work的页面,点那个retry,这个时候Chrome会重新发这个token approve请求,如果rule被执行成功了,就能进入到那个One-time setup, faster checkouts界面了!
一些注意事项:
- 魔改后的JSON很长,我一般在魔改的时候先用个在线的JSON format工具给搞得好看一点,魔改完再用个JSON minify工具给改回成一行然后直接复制进来。原billingNodeServData这里再贴一次:
"billingNodeServData":{"data":{"billingAgreementContext":null},"errors":[{"message":"Cannot read properties of undefined (reading 'country_code')","path":["billingAgreementContext"],"name":"TypeError","extensions":{"class":"FAILURE"},"data":{},"contingency":{},"statusCode":500}]},应该可以直接复制使用 - 如果Rule执行了,Requestly那里会对那个request有高亮提示,而且点进去可以看到rule applied之后的http response。所以如果response没变化,说明rule执行不成功。LZ昨天遇到过好多次rule执行不成功的问题,原因是
replaceAll()里面的两个字符串写得有瑕疵。 - 如果时间间隔太久,paypal可能会自动logout,这个时候重新登录进去再发起这个流程的时候
ecToken和ba_token都会改变,所以得重新改一下魔改的billingNodeServData

