PayPal Payflow 网关 UTF-8 字符

Posted

技术标签:

【中文标题】PayPal Payflow 网关 UTF-8 字符【英文标题】:PayPal Payflow Gateway UTF-8 Characters 【发布时间】:2015-03-25 11:14:51 【问题描述】:

我在让 PayPal Payflow 网关接受包含非 US-ASCII 字符的 HTTPS POST 时遇到问题。不管我用这些特殊字符发布什么,它似乎只想接受 US-ASCII 编码的字节。如果我发送 UTF-8 编码字节,它仍然有效,但无法解析某些请求 NVP 值。我知道这是可能的,因为我已将另一个开发者的测试页面发布到我的帐户(http://ccaples.com/NVP 快速测试),并且该帖子似乎保留了特殊字符。

这是一个例子。我尝试了许多不同的 Content-Type 标头和 Accept/Accept-Charset 值,包括在 text/namevalue 之后的 Content-Type 中指定 "; charset=UTF-8" 或 "; charset=utf-8"。

POST https://pilot-payflowpro.paypal.com/ HTTP/1.1
Content-Type: text/namevalue
User-Agent: KLMS Payflow API for Java
X-VPS-Request-ID: 36A4ED051A8B492ABF70E6BE51CB13D5
X-VPS-CLIENT-TIMEOUT: 20
Connection: close
X-VPS-VIT-INTEGRATION-PRODUCT: KLMS Payflow API for Java
X-VPS-VIT-INTEGRATION-VERSION: 2.0.008
X-VPS-VIT-PROXY: Y
X-VPS-VIT-RUNTIME-VERSION: 20.45-b01
X-VPS-VIT-OS-ARCHITECTURE: amd64
X-VPS-VIT-OS-VERSION: 6.1
X-VPS-VIT-OS-NAME: Windows 7
Cache-Control: no-cache
Pragma: no-cache
Host: pilot-payflowpro.paypal.com
Content-Length: 694

USER[8]=XXXXXXXX&VENDOR[13]=XXXXXXXXXXXXX&PARTNER[6]=PayPal&PWD[8]=XXXXXXXX&VERBOSITY[4]=HIGH&BILLTOEMAIL[28]=XXXXXXXX@kineticlearning.com&TRXTYPE[1]=A&TENDER[1]=C&ACCT[16]=4111111111111111&EXPDATE[4]=1117&CVV2[3]=123&BILLTOFIRSTNAME[4]=Josè&BILLTOLASTNAME[7]=Elkjærd&BILLTOSTREET[14]=123 Elm Street&BILLTOCITY[9]=Elm Creek&BILLTOSTATE[2]=VA&BILLTOZIP[5]=22203&BILLTOCOUNTRY[2]=US&BILLTOPHONENUM[12]=763-221-5593&CUSTBROWSER[108]=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/40.0.2214.91 Safari/537.36&CUSTHOSTNAME[12]=192.168.1.10&CUSTIP[12]=192.168.1.10&AMT[6]=600.00&CURRENCY[3]=USD&COMMENT1[26]=Law Enforcement Curriculum&COMMENT2[16]=Standard Version

HTTP/1.1 200 OK
Connection: close
Server: VPS-3.033.00
X-VPS-Request-ID: 36A4ED051A8B492ABF70E6BE51CB13D5
Date: Sun, 25 Jan 2015 17:45:05 GMT
Content-type: text/namevalue
Content-length: 199

RESULT=104&PNREF=B70P7B6EBAE7&RESPMSG=Timeout waiting for Processor response&TRANSTIME=2015-01-25 09:44:47&BILLTOFIRSTNAME=Jos &BILLTOLASTNAME=NotProvided&AMT=600.00&ACCT=1111&EXPDATE=1117&CARDTYPE=0

暂时忽略 104 超时。贝宝正在为此努力。您可以看到,BILLTOFIRSTNAME 是 Jos(不是 è 的奇怪字符),而 BILLTOLASTNAME 中的 æ 字符肯定导致服务器的 NVP 解析算法完全无法解析,因为它说 NotProvided。

以下是将 NVP 格式的 Java 字符串转换为字节的代码:

        final byte[] requestBytes = requestString.getBytes(Charsets.UTF_8);

知道服务器端 NVP 解析器默认寻找什么字符编码,或者如何告诉它我发送 POST 正文的字符编码是什么?

【问题讨论】:

PayFlow Gateway Docs:The Payflow Gateway only supports customer input and API parameter values that are in regular ASCII (English language) characters. Payflow does not support extended ASCII characters or any other character sets other than regular ASCII at this time 【参考方案1】:

我找到了解决方案。 Payflow Gateway Docs 似乎不支持它。文档似乎已过时,需要更新。我使用 PayPal 支持,看来 Payflow Gateway 支持 UTF-8。这是诀窍:要么您不需要在您提交的名称/值对中指定长度参数(即 BILLTOFIRSTNAME=Josè),要么您必须在长度参数中指定不是 CHARACTERS 中的长度(即不是 value.length( )),但值的 UTF-8 编码字节流的 BYTES 实际长度(即 value.getBytes("UTF-8").length)。此交易有效,存储了 UTF-8 字符并在 PayPal 管理器中正确显示,并且在 Payflow Gateway 响应的名称/值对中返回了正确的值。如您所见,与上面的不同之处在于 BILLTOFIRSTNAME 和 BILLTOLASTNAME 长度标记现在更大,并且指定了以字节为单位的长度而不是以字符为单位的长度。 Josè [4 个字符,5 个字节:4A 6F 73 C3 A8] 和 Elkjærd & Grün [14 个字符,16 个字节:45 6C 6B 6A C3 A6 72 64 20 26 20 47 72 C3 BC 6E]。

POST https://pilot-payflowpro.paypal.com/ HTTP/1.1
Content-Type: text/namevalue
Connection: close
User-Agent: KLMS Payflow for Java/2.0.008
X-VPS-Request-ID: B8DABD9BDFE246EC909B4CF741030133
X-VPS-CLIENT-TIMEOUT: 20
X-VPS-VIT-INTEGRATION-PRODUCT: KLMS Payflow for Java
X-VPS-VIT-INTEGRATION-VERSION: 2.0.008
X-VPS-VIT-PROXY: Y
X-VPS-VIT-RUNTIME-VERSION: 20.45-b01
X-VPS-VIT-OS-ARCHITECTURE: amd64
X-VPS-VIT-OS-VERSION: 6.1
X-VPS-VIT-OS-NAME: Windows 7
Cache-Control: no-cache
Pragma: no-cache
Host: pilot-payflowpro.paypal.com
Content-Length: 771

USER[8]=XXXXXXXX&VENDOR[13]=XXXXXXXXXXXXX&PARTNER[6]=PayPal&PWD[8]=XXXXXXXX&VERBOSITY[4]=HIGH&BILLTOEMAIL[28]=XXXXXX@kineticlearning.com&TRXTYPE[1]=A&TENDER[1]=C&ACCT[16]=4111111111111111&EXPDATE[4]=0216&CVV2[3]=123&BILLTOFIRSTNAME[5]=Josè&BILLTOLASTNAME[16]=Elkjærd & Grün&BILLTOSTREET[14]=123 Elm Street&BILLTOSTREET2[10]=Elm & Vine&BILLTOCITY[9]=Elm Creek&BILLTOSTATE[2]=VA&BILLTOZIP[5]=12345&BILLTOCOUNTRY[2]=US&BILLTOPHONENUM[12]=763-221-5593&CUSTBROWSER[108]=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.91 Safari/537.36&CUSTHOSTNAME[12]=192.168.1.10&CUSTIP[12]=192.168.1.10&AMT[6]=600.00&CURRENCY[3]=USD&COMMENT1[45]=Victim Advocate Curriculum (Standard Version)&COMMENT2[36]=Purchased for J.C. Hamlin (jchamlin)

HTTP/1.1 200 OK
Connection: close
Server: VPS-3.033.00
X-VPS-Request-ID: B8DABD9BDFE246EC909B4CF741030133
Date: Wed, 28 Jan 2015 01:45:29 GMT
Content-type: text/namevalue
Content-length: 209

RESULT=104&PNREF=B10P7D2F1643&RESPMSG=Timeout waiting for Processor response&TRANSTIME=2015-01-27 17:45:12&BILLTOFIRSTNAME=Josè&BILLTOLASTNAME[16]=Elkjærd & Grün&AMT=600.00&ACCT=1111&EXPDATE=0216&CARDTYPE=0

【讨论】:

在 Java 中,value.length 不告诉字符串中的字符数。它仅报告 16 位代码单元的数量,这是一个非常无用且低级的细节。要计算字符,您必须计算整个代码点,而不是在这种或那种编码下的各个组件。 String.length() 有效,但并不完全准确。令人误解的是 String.length() 是 Payflow 的 Java SDK payflow.jar 传递给服务器的内容。此外,Payflow Java SDK 通过调用 String.getBytes() 和 new String(bytes) 使用系统默认编码。 payflow.jar 在这两种情况下都是错误的(即,这两件事都是 Payflow Java SDK 实现中的真正错误,并且与 Payflow Gateway 服务器不兼容)。 经过广泛测试后,这似乎对我不起作用。我看到 Josè Elkjærd & Grün 显示为“Josè Elkjærd & Grün”【参考方案2】:

对于遇到此问题的其他人,我遇到了与 Devin 相同的问题,当我在 Payflow 中查找交易时,è 字符被替换为 è。我不得不将编码转换为 ISO-8859-1。我使用的是 c# 而不是 java,所以这可能不一样,但它就像在我的 Stream Writer 中指定编码一样简单。

using (StreamWriter sw = new StreamWriter(requestStream, Encoding.GetEncoding("ISO-8859-1")))

为什么需要这样做的解释可以在这里找到:https://www.i18nqa.com/debug/bug-utf-8-latin1.html

【讨论】:

以上是关于PayPal Payflow 网关 UTF-8 字符的主要内容,如果未能解决你的问题,请参考以下文章

php [PayPal Pro Payflow]更改PayPal Pro Payflow中的信用卡图标

Payflow 使用 PayPal 帐户创建定期付款

paypal payflow设置视频教程

Paypal 高级付款和 PayFlow 链接与重复付款

如何消除 PayPal Express Checkout 以进行 Payflow 订单审查?

Paypal Payflow 退款问题