123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- package com.fdkankan.pay.util.paypal.sdk;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.fdkankan.pay.common.ResultCode;
- import com.fdkankan.pay.entity.AliConfig;
- import com.fdkankan.pay.entity.Order;
- import com.fdkankan.pay.entity.PaypalConfig;
- import com.fdkankan.pay.exception.BusinessException;
- import com.fdkankan.pay.response.OpenPayResponse;
- import com.fdkankan.pay.service.IOrderService;
- import com.fdkankan.pay.service.IPaypalConfigService;
- import com.fdkankan.pay.util.CacheUtil;
- import com.fdkankan.pay.util.UrlUtils;
- import com.paypal.api.payments.*;
- import com.paypal.base.codec.binary.Base64;
- import com.paypal.base.rest.APIContext;
- import com.paypal.base.rest.PayPalRESTException;
- import lombok.extern.log4j.Log4j2;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.*;
- import java.math.BigDecimal;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.net.URLEncoder;
- import java.util.*;
- @Log4j2
- @Service
- public class PaypalService {
- @Autowired
- IPaypalConfigService paypalConfigService;
- @Autowired
- IOrderService orderService;
- public Object openPay(Order param, String ip) throws Exception {
- String orderSn = param.getOrderSn();
- BigDecimal amount = param.getOrderMoney();
- String subject = param.getOrderType();
- PaypalConfig paypalConfig = paypalConfigService.getByServeId(param.getServeId());
- if(paypalConfig == null){
- throw new BusinessException(ResultCode.PAYPAL_CONFIG_ERROR);
- }
- paypalConfig.setSuccessUrl( CacheUtil.mainUrl + paypalConfig.getCallBackUrl() +"/"+orderSn+"/"+param.getPayType()+"/success");
- paypalConfig.setCancelUrl( CacheUtil.mainUrl + paypalConfig.getCallBackUrl() +"/"+orderSn+"/"+param.getPayType()+"/cancel");
- String body = subject;
- //paypal支付
- if(param.getPayType() == 5){
- return this.payPalPay(orderSn, body, amount,paypalConfig);
- }
- throw new BusinessException(ResultCode.WX_ORDER_PAY_TYPE_ERROR);
- }
- public OpenPayResponse payPalPay(String orderSn, String body, BigDecimal totalFee, PaypalConfig paypalConfig) throws Exception {
- PayPalmentEx payPalmentEx = new PayPalmentEx();
- payPalmentEx.setOrderSn(orderSn);
- payPalmentEx.setOrderTotal(totalFee);
- payPalmentEx.setSubTotal(totalFee);
- payPalmentEx.setDescription(body);
- Payment payment = this.createPayment(payPalmentEx,paypalConfig);
- for(Links links : payment.getLinks()){
- if(links.getRel().equals("approval_url")){
- // 客户付款登陆地址
- OpenPayResponse openPayResponse = new OpenPayResponse();
- openPayResponse.setH5Url(links.getHref());
- openPayResponse.setQrCodeUrl(links.getHref());
- openPayResponse.setOrderSn(orderSn);
- openPayResponse.setPayType(5);
- return openPayResponse;
- }
- }
- throw new BusinessException(ResultCode.PAYPAL_ERROR);
- }
- public Boolean callBack(HttpServletRequest request, HttpServletResponse response, Order order,String result) {
- log.info("paypal-callBack--order:{}",order);
- Boolean payFlag = false;
- String trade_no = null;
- String openId = null;
- if("cancel".equals(result)){
- return false;
- }
- try {
- String paymentId = request.getParameter("paymentId");//商品名
- String payerId = request.getParameter("PayerID");//购买数量
- PaypalConfig paypalConfig = paypalConfigService.getByServeId(order.getServeId());
- if(paypalConfig == null){
- log.error("paypal-callBack--paypalConfig-notexist");
- return false;
- }
- log.info("paypal回调参数:paymentId:{},payerId:{}", paymentId,payerId);
- Payment payment = this.executePayment(paymentId, payerId,paypalConfig);
- if (payment.getState().equals("approved")) {
- log.info("paypal支付成功回调");
- String custom = payment.getTransactions().get(0).getCustom();
- String txnId = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getId();
- String payerEmail = payment.getTransactions().get(0).getPayee().getEmail();
- log.info("paypal-callBack:custom:{},txnid:{},payerEmail:{}",custom,txnId,payerEmail);
- String orderSn = custom.split("_")[0];
- if(custom.split("_").length > 2 && custom.split("_")[2].matches("^-?[0-9]+")){
- orderSn += "_" + custom.split("_")[2];
- }
- payFlag = true;
- trade_no = txnId;
- openId = payerEmail;
- }
- }catch (Exception e) {
- log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
- return false;
- }finally {
- orderService.payResult(order,payFlag,trade_no,openId);
- }
- return true;
- }
- // public Boolean callBack(HttpServletRequest request, HttpServletResponse response, Order order) {
- // log.info("paypal-callBack--order:{}",order);
- // Boolean payFlag = false;
- // String trade_no = null;
- // String openId = null;
- // try {
- // Enumeration en = request.getParameterNames();
- // String str = "cmd=_notify-validate";
- // while (en.hasMoreElements()) {
- // String paramName = (String) en.nextElement();
- // String paramValue = request.getParameter(paramName);
- // try {
- // str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, "utf-8");
- // } catch (UnsupportedEncodingException e) {
- // StringWriter trace=new StringWriter();
- // e.printStackTrace(new PrintWriter(trace));
- // log.error(trace.toString());
- // }
- // //此处的编码一定要和自己的网站编码一致,不然会出现乱码,paypal回复的通知为‘INVALID’
- // }
- // final String itemName = request.getParameter("item_name");//商品名
- // final String itemNumber = request.getParameter("item_number");//购买数量
- // final String paymentDate = request.getParameter("payment_date");//交易时间
- // final String receiverEmail = request.getParameter("receiver_email");//收款人email
- // final String payerEmail = request.getParameter("payer_email");//付款人email
- // final String paymentAmount = request.getParameter("mc_gross");//交易钱数
- // final String paymentCurrency = request.getParameter("mc_currency");//货币种类
- // final String paymentStatus = request.getParameter("payment_status");//交易状态
- // final String txnId = request.getParameter("txn_id");//交易id
- // String custom = request.getParameter("custom");//发送payment请求时候自定义的业务服务器订单号
- // log.info("paypal回调参数:itemName:{},itemNumber:{},paymentDate:{},receiverEmail:{}," +
- // "payerEmail:{},paymentAmount:{},paymentCurrency:{},paymentStatus:{},txnId:{},custom:{}",
- // itemName,itemNumber,paymentDate,receiverEmail,payerEmail,paymentAmount,paymentCurrency,paymentStatus,txnId,custom);
- //
- // trade_no = txnId;
- // openId = payerEmail;
- // if ("Completed".equals(paymentStatus)) {
- // //根据自己业务进行处理(修改订单状态,支付时间等等操作)
- // log.info("paypal支付成功回调");
- // //表示续费,有消费记录id
- // payFlag = true;
- // }
- // }catch (Exception e) {
- // log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
- // return false;
- // }finally {
- // orderService.payResult(order,payFlag,trade_no,openId);
- // }
- // return true;
- // }
- /**
- * 创建支付
- *
- * @param paymentEx
- * @return
- * @throws PayPalRESTException
- */
- @Transactional(rollbackFor = Exception.class)
- public Payment createPayment(PayPalmentEx paymentEx, PaypalConfig paypalConfig) throws PayPalRESTException {
- Transaction transaction = new Transaction();
- transaction.setDescription(paymentEx.getDescription());
- // 将我们的订单ID保存到支付信息中,用于后面支付回传
- if (null != paymentEx.getOrderSn()) {
- transaction.setCustom(paymentEx.getOrderSn());
- }
- //订单价格
- Amount amount = new Amount();
- amount.setCurrency(paypalConfig.getCurrency());
- // 支付的总价,paypal会校验 total = subTotal + tax + ...
- amount.setTotal(paymentEx.getOrderTotal().toString());
- // 设置各种费用
- Details details = new Details();
- // 商品总价
- if (paymentEx.getSubTotal() != null) {
- details.setSubtotal(paymentEx.getSubTotal().toString());
- }
- // 税费
- if (paymentEx.getTax() != null) {
- details.setTax(paymentEx.getTax().toString());
- }
- amount.setDetails(details);
- transaction.setAmount(amount);
- ItemList itemList = new ItemList();
- // 收货地址
- PaypalOrderAddressEx orderAddress = paymentEx.getPaypayOrderAddressEx();
- if (orderAddress != null) {
- ShippingAddress shippingAddress = new ShippingAddress();
- if (StringUtils.isNotEmpty(orderAddress.getFirstName()) && StringUtils.isNotEmpty(orderAddress.getLastName())) {
- shippingAddress.setRecipientName(orderAddress.getFirstName() + "." + orderAddress.getLastName());
- }
- shippingAddress.setCountryCode(orderAddress.getCountryCode());
- shippingAddress.setState(orderAddress.getState());
- shippingAddress.setCity(orderAddress.getCity());
- shippingAddress.setLine1(orderAddress.getAddress());
- shippingAddress.setPhone(orderAddress.getPhone());
- shippingAddress.setPostalCode(orderAddress.getPostalCode());
- itemList.setShippingAddress(shippingAddress);
- itemList.setShippingPhoneNumber(orderAddress.getPhone());
- }
- // 商品明细
- List<PaypalOrderItemEx> orderItemList = paymentEx.getPaypalOrderItemExList();
- if (orderItemList != null && orderItemList.size() > 0) {
- List<Item> items = new ArrayList<>();
- for (PaypalOrderItemEx orderItemEx : orderItemList) {
- Item item = new Item();
- item.setSku(orderItemEx.getSku());
- item.setName(orderItemEx.getName());
- item.setPrice(orderItemEx.getPrice().toString());
- item.setQuantity(String.valueOf(orderItemEx.getQuantity()));
- item.setCurrency(paypalConfig.getCurrency());
- 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();
- //刷新accessToken时间;
- APIContext apiContext = new APIContext("Bearer " + getAccessToken(paypalConfig));
- Map<String, String> sdkConfig = new HashMap<>();
- sdkConfig.put("mode", paypalConfig.getMode());
- apiContext.setConfigurationMap(sdkConfig);
- payment.setIntent(PaypalPaymentIntent.sale.toString());
- payment.setPayer(payer);
- payment.setTransactions(transactions);
- //回调地址
- RedirectUrls redirectUrls = new RedirectUrls();
- redirectUrls.setReturnUrl(paypalConfig.getSuccessUrl());
- redirectUrls.setCancelUrl(paypalConfig.getCancelUrl());
- payment.setRedirectUrls(redirectUrls);
- return payment.create(apiContext);
- }
- /**
- * 执行支付
- *
- * @param paymentId
- * @param payerId
- * @return
- * @throws PayPalRESTException
- */
- public Payment executePayment(String paymentId, String payerId,PaypalConfig paypalConfig) throws PayPalRESTException {
- Payment payment = new Payment();
- payment.setId(paymentId);
- PaymentExecution paymentExecute = new PaymentExecution();
- paymentExecute.setPayerId(payerId);
- APIContext apiContext = new APIContext("Bearer " + getAccessToken(paypalConfig));
- Map<String, String> sdkConfig = new HashMap<>();
- sdkConfig.put("mode", paypalConfig.getMode());
- apiContext.setConfigurationMap(sdkConfig);
- return payment.execute(apiContext, paymentExecute);
- }
- /**
- * 获取token
- * 了解更多:https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-mobile-payment/
- * @return
- */
- private String getAccessToken(PaypalConfig paypalConfig) {
- BufferedReader reader = null;
- try {
- URL url = new URL(UrlUtils.TOKEN_URL);
- String authorization = paypalConfig.getClientId() + ":" + paypalConfig.getSecret();
- authorization = Base64.encodeBase64String(authorization.getBytes());
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("POST");// 提交模式
- //设置请求头header
- conn.setRequestProperty("Accept", "application/json");
- conn.setRequestProperty("Accept-Language", "en_US");
- conn.setRequestProperty("Authorization", "Basic " + authorization);
- // conn.setConnectTimeout(10000);//连接超时 单位毫秒
- // conn.setReadTimeout(2000);//读取超时 单位毫秒
- conn.setDoOutput(true);// 是否输入参数
- String params = "grant_type=client_credentials";
- conn.getOutputStream().write(params.getBytes());// 输入参数
- InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
- reader = new BufferedReader(inStream);
- StringBuilder result = new StringBuilder();
- String lineTxt = null;
- while ((lineTxt = reader.readLine()) != null) {
- result.append(lineTxt);
- }
- reader.close();
- //log.info("getAccessToken:" + accessTokey);
- return JSONObject.parseObject(result.toString()).getString("access_token");
- } catch (Exception err) {
- err.printStackTrace();
- } finally {
- if (reader != null){
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return null;
- }
- public String getPaymentDetails(String paymentId,PaypalConfig paypalConfig) {
- BufferedReader reader = null;
- try {
- URL url = new URL(UrlUtils.PAYMENT_DETAIL + paymentId);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");// 提交模式
- //设置请求头header
- conn.setRequestProperty("Accept", "application/json");
- conn.setRequestProperty("Authorization", "Bearer " + getAccessToken(paypalConfig));
- // conn.setConnectTimeout(10000);//连接超时 单位毫秒
- // conn.setReadTimeout(2000);//读取超时 单位毫秒
- InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
- reader = new BufferedReader(inStream);
- StringBuilder result = new StringBuilder();
- String lineTxt = null;
- while ((lineTxt = reader.readLine()) != null) {
- result.append(lineTxt);
- }
- reader.close();
- return result.toString();
- } catch (Exception err) {
- err.printStackTrace();
- }finally {
- if (reader != null){
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return null;
- }
- public boolean verifyPayment(String paymentId,PaypalConfig paypalConfig){
- //从PayPal获取付款详情
- String str = getPaymentDetails(paymentId,paypalConfig);
- JSONObject detail = JSONObject.parseObject(str);
- //校验订单是否完成
- if("approved".equals(detail.getString("state"))){
- JSONObject transactions = detail.getJSONArray("transactions").getJSONObject(0);
- JSONObject amount = transactions.getJSONObject("amount");
- JSONArray relatedResources = transactions.getJSONArray("related_resources");
- //从数据库查询总金额与Paypal校验支付总金额
- double total = 0;
- if( total != amount.getDouble("total") ){
- return false;
- }
- //校验交易货币类型
- String currency = "USD";
- if( !currency.equals(amount.getString("currency")) ){
- return false;
- }
- //校验每个子订单是否完成
- for (int i = 0,j = relatedResources.size(); i < j; i++) {
- JSONObject sale = relatedResources.getJSONObject(i).getJSONObject("sale");
- if( !"completed".equals(sale.getString("state")) ){
- System.out.println("子订单未完成,订单状态:"+sale.getString("state"));
- }
- }
- return true;
- }
- return false;
- }
- }
|