Paypal标准支付对接
提醒一下,题主是在快速标准支付做到一半的时候换成了标准支付,所以该文档的快速支付大家做个参考就可以了.
一、两种支付方式
标准支付
- 优点:纯前端对接,简单方便,适用于非技术开发人员.个人即可用,不用花一个月时间进行商家认证(需要营业执照)
- 缺点:对接简单也就意味着无法执行复杂的工作,无法进行回调(因为本身就是给非技术开发人员使用的,如果这里有人发现可以回调请记得回来打我的脸!)
使用
快速支付
- 优点:可以进行回调,对接较为复杂的业务
- 缺点:开发难度大,需要相关的营业资质
二、沙盒使用
地址:https://developer.paypal.com/developer/applications/
为什么要使用沙盒环境:
- 快速支付的开通需要对应有国内相关的营业执照,但是通过沙盒环境我们可以直接获得一个仅在沙盒环境下可用的商家app
- paypal作为国外的支付手段是无法直接使用国内的银行卡支付的,需要使用visa等卡
使用:
- 创建相关账号
- 点击
Sandbox -> account,进入主页的account下,分别创建一个商家账号和买家账号 - (标准支付)登陆https://www.sandbox.paypal.com/,创建按钮
- (快速支付)点击
Dashboard -> My Account,以商家账号为基础创建一个app,在开发快速支付时使用
三、标准支付
创建账号
创建相关的按钮,即生成对应的html代码
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="D7U8ME8UVW5MG">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif" border="0" name="submit" alt="PayPal——最安全便捷的在线支付方式!">
<img alt="" border="0" src="https://www.paypalobjects.com/zh_XC/i/scr/pixel.gif" width="1" height="1">
</form>
将代码嵌入到对应的页面即可(这里不放相关的代码了,因为都是和业务深度内嵌的)
补充:
- 按钮的代码可以定制不同的规格选项
- 看清楚按钮的本质:将相关的cmd,hosted_button_id等参数以post形式传送到https://www.paypal.com/cgi-bin/webscr,返回一个对应的支付页面
- 如果按钮的排版布局无法满足你的要求,比如你需要将不同的支付手段(如微信支付)集成到同一个按钮,可以设置一个能选择不同支付手段的按钮选项,根据这个选项间接地用js调用paypal支付按钮
- paypal不支持国内的支付手段,支付需要使用VISA
四、快速支付
注:
- 本代码主要参考了这篇博客.遗憾的是,这篇博客距今已经有三年历史了,所以其实本人还使用了其它的博客进行参考,由于篇幅所限就不一一列举了.
- 由于本人没有visa的卡+该方案最终没有被采纳(因为相关资质的审核需要30天),实际本代码的可用性仅到订单生成为止,还无法确定回调是否可行
创建相关账号
获得app(这里具体的地址应该和沙盒一样,遗憾的是我个人并没有实际使用过)
sdk下载:
开发
public Payment createPayment(Map<String,String> paraMap) throws PayPalRESTException { Transaction transaction = new Transaction();
transaction.setDescription("icwlRegister");
// 将我们的订单ID保存到支付信息中,用于后面支付回传
if (null != paraMap.get("user_id")) {
transaction.setCustom(paraMap.get("user_id"));
}
/**
* 订单价格
* 注意两个公式:
* 1. total = subtotal(商品总额) + tax(税) + shopping(邮费) + other
* 2. subtotal = product1*num1+...
* 注意:如果有优化活动的话要坑
*/
Amount amount = new Amount();
// 设置各种费用
amount.setCurrency("USD"); //其实在paypal的返回值有说什么是哪个类哪个字段的问题
// 商品总价
amount.setTotal(paraMap.get("order_amount")); Details details = new Details();
details.setSubtotal(paraMap.get("order_amount"));
// 税费
details.setTax("0"); amount.setDetails(details); transaction.setAmount(amount); ItemList itemList = new ItemList();
//收获地址不设置 /**
* 商品明细
*/
List<Item> items = new ArrayList<>();
Item item = new Item();
item.setSku("PRODUCT0000001");
item.setName("register");
item.setPrice(paraMap.get("order_amount"));
item.setQuantity("1");
item.setCurrency("USD"); //货币种类,注意应该不支持人民币
items.add(item); itemList.setItems(items);
transaction.setItemList(itemList); List<Transaction> transactions = new ArrayList<>();
transactions.add(transaction); /**
* 支付信息
*/
Payer payer = new Payer();
payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString()); Payment payment = new Payment();
payment.setIntent(PaypalPaymentIntent.sale.toString());
payment.setPayer(payer);
payment.setTransactions(transactions); /**
* 回调地址
*/
RedirectUrls redirectUrls = new RedirectUrls();
redirectUrls.setReturnUrl("http://..."); //成功支付后的回调地址
redirectUrls.setCancelUrl("www.baidu.com"); //支付失败后的回调地址
payment.setRedirectUrls(redirectUrls);
System.out.println("调用之前:" + payment); // 创建paypal API对象
APIContext apiContext = new APIContext(paypalConfigBean.getClientId(), paypalConfigBean.getClientSecret(), paypalConfigBean.getMode());
return payment.create(apiContext);
} @Override
public String paypalService(Map map) throws PayPalRESTException { HashMap<String, Object> resMap = new HashMap<>(); //paypal
Payment payment = createPayment( map ); //订单成功的回调地址
System.out.println("调用之后:" + payment);
for(Links links : payment.getLinks()){
if(links.getRel().equals("approval_url")){
resMap.put("url",links.getHref());
}
} //数据库操作
map.put("payment_id",payment.getId()); //获得paypal的唯一识别id
System.out.println(map.get("payment_id"));
Integer maxUserId = userMapper.getMaxUserId();
Integer id = maxUserId==null?1:maxUserId+1;
System.out.println("id:" +id);
map.put("user_id",id.toString());
userMapper.addUser(map);
resMap.put("id",id);
return JsonUtil.toJsonString(resMap);
} @Override
public void paypalNotify(String paymentId) {
Integer userId = userMapper.getUserIdByPaymentId(paymentId);
if(userId != null){
String dateFormat = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
userMapper.updateUserById(userId,sdf.format(new Date()));
}else{
System.out.println("Wrong!");
}
} @Override
public String getUserId(Map map) {
Integer maxUserId = userMapper.getMaxUserId();
Integer id = maxUserId==null?1:maxUserId+1;
map.put("user_id",id);
userMapper.addUser(map);
//结果集
Map<String, Object> resMap = new HashMap<String, Object>();
resMap.put("userId",id);
return JsonUtil.toJsonString(resMap);
}
注:
这里的代码参考意义更强一些,因为没有完工,很烂(留着给自己做个记录吧)
订单价格的两个公式(如果不正确也是会报错的):
1. total = subtotal(商品总额) + tax(税) + shopping(邮费) + other
2. subtotal = product1*num1+..
总结一下
- paypal支付的对接过程在我看来是非常糟心的,因为缺少相关的中文文档(自己这方面的能力的确还不足)
- 相关的api设置还不够完善,曾经的微信支付的api也是乱七八糟的,但现在都有了比较统一的接口.就比如关于价格的严格规则,其实就可以做成api调用,即总价格由计算得出,当然可能paypal本身的考虑也可能是为了使开发者避免单价价格和税率,总价的不一致性,那么我只能说这波paypal是在大气层!
Paypal标准支付对接的更多相关文章
- PayPal支付对接
开发时间:2019-04-30 我的目标:在我们公司的海外网站上,接入PayPal支付,美国用户在线完成付款. 准备: (1)准备:公司注册信息(执照,注册号,法人等),法人信息(身份证,住址等) ( ...
- [label][转载][paypal]paypal在线支付接口的WEB语言设置
http://stephen830.iteye.com/blog/274072 ★★★ 本篇为原创,需要引用转载的朋友请注明:< http://stephen830.iteye.com/blog ...
- Stripe支付对接
一.由于文档丢失原因,我就直接上代码了. 这个Stripe支付可以支持多个币种,我下面就采用"HDK"来参照支付先上一个支付效果图 提示:先上代码,在说明博主自己理解的流程. 一 ...
- Razorpay支付对接,JAVA对接篇
Razorpay 作为印度本土的一家支付公司,类似中国的支付宝 微信,本篇记录一下对接印度第三方支付公司 准备工作: 注册公司 申请Razorpay账号 申请正式环境 Razorpay工作台: 获取k ...
- C#微信支付对接
c#版在pc端发起微信扫码支付 主要代码: /** * 生成直接支付url,支付url有效期为2小时,模式二 * @param productId 商品ID * @return 模式二URL */ ...
- ecshop移动端支付宝支付对接
初始页,提交基本信息到api页面, <?php /* * * 功能:支付宝手机网站支付接口接口调试入口页面 * 版本:3.4 * 修改日期:2016-03-08 * 说明: * 以下代码只是为了 ...
- 海外支付:遍布全球的Paypal
海外支付:遍布全球的Paypal 吴剑 2015-11-26 原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian 吴剑 http://www.cnblogs.co ...
- PayPal网站付款标准版(for PHP)
简单整理一下PHP项目整合PayPal支付功能. 一.表单的构建: <form method="post" name="form" action=&quo ...
- 基于ASP.NET/C#开发国外支付平台(Paypal)学习心得。
最近一直在研究Paypal的支付平台,因为本人之前没有接触过接口这一块,新来一家公司比较不清楚流程就要求开发两个支付平台一个是支付宝(这边就不再这篇文章里面赘述了),但还是花了2-3天的时间通 ...
随机推荐
- JS 获取JSON返回的时间值转换为通常格式展示
var date = new Date(parseInt(数据源.slice(6))); //获取到时间 年月日时分秒 var result = date.getFullYear() + '/' ...
- 浅谈Java面向对象之抽象类(abstract)
java语言,声明类时格式为: abstract class Db{} 说明Db类为抽象类.抽象方法是说没有方法的实现(方法体)此方法为抽象方法,只有抽象类和接口中才可以有抽象方法.简而言之,含有抽象 ...
- ConcurrentHashMap怎么保证安全的
HashMap是一个线程不安全的容器,当容量大于总量*负载因子发生扩容时可能会出现环形链表从而导致死循环 扩容就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下, ...
- 基于FMC接口的Kintex-7 XC7K325T PCIeX4 3U VPX接口卡
一.板卡概述 标准VPX 3U板卡, 基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8.64b ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- .NET 云原生架构师训练营(权限系统 代码实现 WebApplication)--学习笔记
目录 开发任务 代码实现 开发任务 DotNetNB.Security.Core:定义 core,models,Istore:实现 default memory store DotNetNB.WebA ...
- Python小游戏之 - 飞机大战 !
用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...
- Vue-从入门到第三次世界大战_1
前言:当然世界大战是大家都不希望看到的这里是代表我会一直更新下去 ,那我为什么要这么写,没错我就是标题党. 先说下Vue介绍: 官网:https://cn.vuejs.org/ 为什么用:因为是TMD ...
- Android SugarORM(1)
Android Sugar ORM (1) Android Sugar ORM比我之前用过的ORM都要简单许多, 其目的是简化与Android中SQLite数据库的交互, 优点如下: 消除了编写SQL ...
- java高版本下各种JNDI Bypass方法复现
目录 0 前言 1 Java高版本JNDI绕过的源代码分析 1.1 思路一的源码分析 1.2 思路二的源码分析 2 基于本地工厂类的利用方法 2.1 org.apache.naming.factory ...