Heim  >  Artikel  >  php教程  >  paypal php 对接

paypal php 对接

WBOY
WBOYOriginal
2016-06-14 00:02:544201Durchsuche

项目需要要在php中使用paypal支付。

先吐槽下paypal,以前做过国内的一些支付接口,有些经验。想到的是直接找paypal客服要接口文档。

尼玛加paypal客服QQ  不在线。几天如此。这么大的支付居然没技术支持,真不能理解。文档后面还是在官网7找8找才找到了。

 

正文:

首先要在sandbox环境申请主帐号。连接:https://developer.paypal.com/

申请后用主帐号登录申请卖家以及买家帐号。然后进行一些设置。

注意:如果买家是国外的,那么创建买家帐号的时候就要设置所在国家。这样在支付页面才会以该国家的语言显示界面。

申请帐号以及设置问题请参考文档  连接:https://www.paypal-biz.com/development/documentation/PayPal_Sandbox_Guide_CN_V2.0.pdf

 

支付过程首先第一步是提交表单给paypal 当然post方式。

<span style="color: #0000ff;"><span style="color: #800000;">form </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="form_starPay"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="form_starPay"</span><span style="color: #ff0000;"> action</span><span style="color: #0000ff;">="https://www.sandbox.paypal.com/cgi-bin/webscr"</span><span style="color: #ff0000;"> method</span><span style="color: #0000ff;">="post"</span><span style="color: #0000ff;">></span>
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="cmd"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="_xclick"</span><span style="color: #0000ff;">></span> //告诉paypal该表单是立即购买
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="business"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="XXXXXX@XXXXX.com"</span><span style="color: #0000ff;">></span> //卖家帐号  也就是收钱的帐号
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="item_name"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="name"</span><span style="color: #0000ff;">></span> //商品名称
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="amount"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="10000"</span><span style="color: #0000ff;">></span> //价格
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="currency_code"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="JPY"</span><span style="color: #0000ff;">></span> //币种
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="return"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="http://localhost/frontend/pay/PDT_order"</span><span style="color: #0000ff;">> //支付成功后网页跳转地址</span>
<span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="notify_url"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="http://localhost/frontend/pay/IPN_Order"</span><span style="color: #0000ff;">> </span>//支付成功后paypal后台发送订单通知地址<br><span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="invoice"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">=""</span><span style="color: #0000ff;">> //自定义订单号   paypal原样返回<br></span><span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="custom"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">=""</span><span style="color: #0000ff;">></span><span style="line-height: 1.5;"> // 自定义变量  paypal原样返回<br></span><span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="hidden"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="lc"</span><span style="color: #ff0000;"> value</span><span style="color: #0000ff;">="JP"</span><span style="color: #0000ff;">></span><span style="line-height: 1.5;"> //支付页面语言设置<br></span><span style="color: #0000ff;"><span style="color: #800000;">input </span><span style="color: #ff0000;">style</span><span style="color: #0000ff;">="visibility:hidden"</span><span style="color: #ff0000;"> type</span><span style="color: #0000ff;">="image"</span><span style="color: #ff0000;"> src</span><span style="color: #0000ff;">=" https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif "</span><span style="color: #ff0000;"> border</span><span style="color: #0000ff;">="0"</span><span style="color: #ff0000;"> name</span><span style="color: #0000ff;">="submit"</span><span style="color: #ff0000;"> alt</span><span style="color: #0000ff;">=" PayPal - The safer, easier way to pay online"</span><span style="color: #0000ff;">>//支付按钮<br><br></span><span style="color: #0000ff;"></span><span style="color: #800000;">form</span><span style="color: #0000ff;">></span></span></span></span></span></span></span></span></span></span></span></span></span>

当支付成功后 paypal就会跳转到我们设置的 “return” 地址,会带上一个流水号 我们get方式就可以取到值。流水号键名 “tx”。

拿到流水号然后加上身份标识跟cmd变量就可以到paypal请求刚才支付的订单的交易内容。

例如:cmd=_notify-synch&tx=123sflsfjlw12&tx_token=fsfljvw3lwejloj43jfvdflf2

cmd=_notify-synch是告诉paypal你要做什么,这里是查询订单交易。

tx_token值要在paypal后台取,刚才注册帐号的时候要开通pdt功能才行。

这个过程paypal称为:PDT (Payment Data Transfer 付款数据传输)。

我们接收到返回的一些数据后就可以进行一些支付后的操作,比如发金币,发货等等。

pdt 详细的返回参数最后给出文档。

代码:

<span style="color: #000000;">php 
</span><span style="color: #008000;">//</span><span style="color: #008000;">获取 PayPal 交易流水号 tx </span>
<span style="color: #800080;">$tx_token</span> = <span style="color: #800080;">$_GET</span>['tx'<span style="color: #000000;">]; 
</span><span style="color: #008000;">//</span><span style="color: #008000;">定义您的身份标记 </span>
<span style="color: #800080;">$auth_token</span> = "CHANGE-TO-YOUR-TOKEN"<span style="color: #000000;">; 
</span><span style="color: #008000;">//</span><span style="color: #008000;">形成验证字符串 </span>
<span style="color: #800080;">$req</span> = " cmd=_notify-synch&tx=<span style="color: #800080;">$tx_token</span>&at=<span style="color: #800080;">$auth_token</span>"<span style="color: #000000;">; 
</span><span style="color: #008000;">//</span><span style="color: #008000;">将交易流水号及身份标记返回 PayPal 验证 </span>
<span style="color: #800080;">$header</span> .= "POST /cgi-bin/webscr HTTP/1.0\r\n"<span style="color: #000000;">; 
</span><span style="color: #800080;">$header</span> .= "Content-Type: application/x-www-form-urlencoded\r\n"<span style="color: #000000;">; 
</span><span style="color: #800080;">$header</span> .= "Content-Length: " . <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$req</span>) . "\r\n\r\n"<span style="color: #000000;">; 
</span><span style="color: #800080;">$fp</span> = <span style="color: #008080;">fsockopen</span> ('www.paypal.com', 80, <span style="color: #800080;">$errno</span>, <span style="color: #800080;">$errstr</span>, 30<span style="color: #000000;">); 
</span><span style="color: #0000ff;">if</span> (!<span style="color: #800080;">$fp</span><span style="color: #000000;">) { 
</span><span style="color: #008000;">//</span><span style="color: #008000;"> HTTP ERROR </span>
} <span style="color: #0000ff;">else</span><span style="color: #000000;"> { 
</span><span style="color: #008080;">fputs</span> (<span style="color: #800080;">$fp</span>, <span style="color: #800080;">$header</span> . <span style="color: #800080;">$req</span><span style="color: #000000;">); 
</span><span style="color: #008000;">//</span><span style="color: #008000;">获取返回数据 </span>
<span style="color: #800080;">$res</span> = ''<span style="color: #000000;">; 
</span><span style="color: #800080;">$headerdone</span> = <span style="color: #0000ff;">false</span><span style="color: #000000;">; 
</span><span style="color: #0000ff;">while</span> (!<span style="color: #008080;">feof</span>(<span style="color: #800080;">$fp</span><span style="color: #000000;">)) { 
</span><span style="color: #800080;">$line</span> = <span style="color: #008080;">fgets</span> (<span style="color: #800080;">$fp</span>, 1024<span style="color: #000000;">); 
</span><span style="color: #0000ff;">if</span> (<span style="color: #008080;">strcmp</span>(<span style="color: #800080;">$line</span>, "\r\n") == 0<span style="color: #000000;">) { 
</span><span style="color: #008000;">//</span><span style="color: #008000;">获取头 </span>
<span style="color: #800080;">$headerdone</span> = <span style="color: #0000ff;">true</span><span style="color: #000000;">; 
}</span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (<span style="color: #800080;">$headerdone</span><span style="color: #000000;">){ 
</span><span style="color: #008000;">//</span><span style="color: #008000;">获取主体内容 </span>
<span style="color: #800080;">$res</span> .= <span style="color: #800080;">$line</span><span style="color: #000000;">; 
} 
} 
</span><span style="color: #008000;">//</span><span style="color: #008000;">解析获取内容 </span>
<span style="color: #800080;">$lines</span> = <span style="color: #008080;">explode</span>("\n", <span style="color: #800080;">$res</span><span style="color: #000000;">); 
</span><span style="color: #800080;">$keyarray</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); 
</span><span style="color: #0000ff;">if</span> (<span style="color: #008080;">strcmp</span> (<span style="color: #800080;">$lines</span>[0], "SUCCESS") == 0<span style="color: #000000;">) { 
</span><span style="color: #0000ff;">for</span> (<span style="color: #800080;">$i</span>=1; <span style="color: #800080;">$i</span>count(<span style="color: #800080;">$lines</span>);<span style="color: #800080;">$i</span>++<span style="color: #000000;">){ 
</span><span style="color: #0000ff;">list</span>(<span style="color: #800080;">$key</span>,<span style="color: #800080;">$val</span>) = <span style="color: #008080;">explode</span>("=", <span style="color: #800080;">$lines</span>[<span style="color: #800080;">$i</span><span style="color: #000000;">]); 
</span><span style="color: #800080;">$keyarray</span>[<span style="color: #008080;">urldecode</span>(<span style="color: #800080;">$key</span>)] = <span style="color: #008080;">urldecode</span>(<span style="color: #800080;">$val</span><span style="color: #000000;">); 
} 
</span><span style="color: #008000;">//</span><span style="color: #008000;">检查交易付款状态 payment_status 是否为  „Completed‟ 
//检查交易流水号 txn_id 是否已经被处理过 
//检查接收 EMAIL receiver_email 是否为您的 PayPal 中已经注册的 EMAIL 
//检查金额 mc_gross 是否正确 
//…… 
//处理此次付款明细 
//该付款明细所有变量可参考: 
//https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html </span>
<span style="color: #800080;">$name</span> = <span style="color: #800080;">$keyarray</span>['first_name'] . ' ' . <span style="color: #800080;">$keyarray</span>['last_name'<span style="color: #000000;">]; 
</span><span style="color: #800080;">$itemname</span> = <span style="color: #800080;">$keyarray</span>['item_name'<span style="color: #000000;">]; 
</span><span style="color: #800080;">$amount</span> = <span style="color: #800080;">$keyarray</span>['mc_gross'<span style="color: #000000;">]; 
</span><span style="color: #0000ff;">echo</span> ("<p></p><h3>Thank you for you purchase!</h3>"<span style="color: #000000;">); 
</span><span style="color: #0000ff;">echo</span> ("<b>Payment Details:</b><br>\n"<span style="color: #000000;">); 
</span><span style="color: #0000ff;">echo</span> ("
  • Name: $name
  • \n"); echo ("
  • Item: $itemname
  • \n"); echo ("
  • Amount: $amount
  • \n"); }else if (strcmp ($lines[0], "FAIL") == 0) { //获取付款明细失败,记录并检查 } } fclose ($fp); ?>

     

     

    为了防止用户关掉浏览器,订单通知不到的情况。paypal还提供了一种通知方式:IPN (Instant Payment Notification 即时付款通知);

    IPN 是在后台进行http请求通知。

    当开通了ipn功能,并且订单状态发生改变的时候,paypal会主动请求我们支付表单中变量“notify_url”提供的地址。

    我们在接收到paypal请求后要拿到所有的数据

    然后用 “cmd=_notify-validate”加上刚才的数据,http发送给paypal进行验证,以防请求是伪造的。

    代码:

    <span style="color: #000000;">php 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">从 PayPal 出读取 POST 信息同时添加变量„cmd‟ </span>
    <span style="color: #800080;">$req</span> = 'cmd=_notify-validate'<span style="color: #000000;">; 
    </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$_POST</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$key</span> => <span style="color: #800080;">$value</span><span style="color: #000000;">) { 
    </span><span style="color: #800080;">$value</span> = <span style="color: #008080;">urlencode</span>(<span style="color: #008080;">stripslashes</span>(<span style="color: #800080;">$value</span><span style="color: #000000;">)); 
    </span><span style="color: #800080;">$req</span> .= "&<span style="color: #800080;">$key</span>=<span style="color: #800080;">$value</span>"<span style="color: #000000;">; 
    } 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">建议在此将接受到的信息记录到日志文件中以确认是否收到 IPN 信息 
    //将信息 POST 回给 PayPal 进行验证 </span>
    <span style="color: #800080;">$header</span> .= "POST /cgi-bin/webscr HTTP/1.0\r\n"<span style="color: #000000;">; 
    </span><span style="color: #800080;">$header</span> .= "Content-Type:application/x-www-form-urlencoded\r\n"<span style="color: #000000;">; 
    </span><span style="color: #800080;">$header</span> .= "Content-Length:" . <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$req</span>) ."\r\n\r\n"<span style="color: #000000;">; 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">在 Sandbox 情况下,设置: 
    //$fp = fsockopen(„www.sandbox.paypal.com‟,80,$errno,$errstr,30); </span>
    <span style="color: #800080;">$fp</span> = <span style="color: #008080;">fsockopen</span> ('www.paypal.com', 80, <span style="color: #800080;">$errno</span>, <span style="color: #800080;">$errstr</span>, 30<span style="color: #000000;">); 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">将 POST 变量记录在本地变量中 
    //该付款明细所有变量可参考: 
    //https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html </span>
    <span style="color: #800080;">$item_name</span> = <span style="color: #800080;">$_POST</span>['item_name'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$item_number</span> = <span style="color: #800080;">$_POST</span>['item_number'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$payment_status</span> = <span style="color: #800080;">$_POST</span>['payment_status'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$payment_amount</span> = <span style="color: #800080;">$_POST</span>['mc_gross'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$payment_currency</span> = <span style="color: #800080;">$_POST</span>['mc_currency'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$txn_id</span> = <span style="color: #800080;">$_POST</span>['txn_id'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$receiver_email</span> = <span style="color: #800080;">$_POST</span>['receiver_email'<span style="color: #000000;">]; 
    </span><span style="color: #800080;">$payer_email</span> = <span style="color: #800080;">$_POST</span>['payer_email'<span style="color: #000000;">]; 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">… 
    //判断回复 POST 是否创建成功 </span>
    <span style="color: #0000ff;">if</span> (!<span style="color: #800080;">$fp</span><span style="color: #000000;">) { 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">HTTP 错误 </span>
    }<span style="color: #0000ff;">else</span><span style="color: #000000;"> { 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">将回复 POST 信息写入 SOCKET 端口 </span>
    <span style="color: #008080;">fputs</span> (<span style="color: #800080;">$fp</span>, <span style="color: #800080;">$header</span> .<span style="color: #800080;">$req</span><span style="color: #000000;">); 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">开始接受 PayPal 对回复 POST 信息的认证信息 </span>
    <span style="color: #0000ff;">while</span> (!<span style="color: #008080;">feof</span>(<span style="color: #800080;">$fp</span><span style="color: #000000;">)) { 
    </span><span style="color: #800080;">$res</span> = <span style="color: #008080;">fgets</span> (<span style="color: #800080;">$fp</span>, 1024<span style="color: #000000;">); 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">已经通过认证 </span>
    <span style="color: #0000ff;">if</span> (<span style="color: #008080;">strcmp</span> (<span style="color: #800080;">$res</span>, "VERIFIED") == 0<span style="color: #000000;">) { 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">检查付款状态 
    //检查 txn_id 是否已经处理过 
    //检查 receiver_email 是否是您的 PayPal 账户中的 EMAIL 地址 
    //检查付款金额和货币单位是否正确 
    //处理这次付款,包括写数据库 </span>
    }<span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (<span style="color: #008080;">strcmp</span> (<span style="color: #800080;">$res</span>, "INVALID") == 0<span style="color: #000000;">) { 
    </span><span style="color: #008000;">//</span><span style="color: #008000;">未通过认证,有可能是编码错误或非法的 POST 信息 </span>
    <span style="color: #000000;">} 
    } 
    </span><span style="color: #008080;">fclose</span> (<span style="color: #800080;">$fp</span><span style="color: #000000;">); 
    } 
    </span>?> 

     

    接口对接就这样好了,搞清楚了流程很简单。

    如果币种不是paypal默认的,在订单支付后订单状态一直是pending, 用卖家帐号登录在订单状态哪里点击接收,paypal就会自动设置接收该币种功能。

    技术文档地址:https://www.paypal-biz.com/developer/documentation/2134.html

     

     

     

     

     

    Stellungnahme:
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn