paypal项目

common文件夹

package com.stop.think.shiro.common;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PayPalConfig {


  public static String CLIENT_ID;
  @Value("${paypal.client.id}")
  public void setClientId(String clientId) {
    PayPalConfig.CLIENT_ID = clientId;
  }

  public static String CLIENT_SECRET;
  @Value("${paypal.client.secret}")
  public void setClientSecret(String clientSecret) {
    PayPalConfig.CLIENT_SECRET = clientSecret;
  }

  public static String BRAND_NAME;
  @Value("${paypal.brand.name}")
  public void setBrandName(String brandName) {
    PayPalConfig.BRAND_NAME = brandName;
  }

  public final static String LANDING_PAGE = "NO_PREFERENCE";
  public final static String SHIPPING_PREFERENCE = "NO_SHIPPING";
  public final static String USER_ACTION = "PAY_NOW";
  public final static String INTENT = "CAPTURE";
}

package com.stop.think.shiro.common;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ProjectConfig {

  public static boolean IS_TEST = true;

  @Value("${is.test}")
  public void setIsTest(boolean isTest) {
    IS_TEST = isTest;
  }
}

 DAO  OrderRecord

package com.stop.think.shiro.dao.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Entity
@Table
@Getter
@Setter
public class OrderRecord {

    public final static String STATUS_ING = "01";
    public final static String STATUS_SUC = "02";
    public final static String STATUS_FAIL = "03";

    @Id
    private String id;

    private String name;

    private BigDecimal money;

    /***
     * 币种
     */
    private String currencyCode;

    private String mark;

    /**
     * 支付订单号
     */
    @Column(nullable = false, length = 200, unique = true)
    private String payOrdNo;

    private LocalDateTime payDate;

    private LocalDateTime createDate;

    private String status;
}
package com.stop.think.shiro.dao;

import com.stop.think.shiro.dao.entity.OrderRecord;
import org.springframework.data.repository.PagingAndSortingRepository;

import java.util.Optional;

public interface OrderRecordDao extends PagingAndSortingRepository<OrderRecord, Long> {

    Optional<OrderRecord> findByPayOrdNo(String payOrdNo);
}

service

package com.stop.think.shiro.service.paypal;

import com.paypal.core.PayPalEnvironment;
import com.paypal.core.PayPalHttpClient;
import com.stop.think.shiro.common.PayPalConfig;
import com.stop.think.shiro.common.ProjectConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class PayPalClient {

  private static PayPalHttpClient client;

  private PayPalClient() {}

  public static PayPalHttpClient client() {
    if (client != null) {
      return client;
    }
    PayPalEnvironment environment = !ProjectConfig.IS_TEST ? new PayPalEnvironment.Live(PayPalConfig.CLIENT_ID, PayPalConfig.CLIENT_SECRET)
            : new PayPalEnvironment.Sandbox(PayPalConfig.CLIENT_ID, PayPalConfig.CLIENT_SECRET);
    client = new PayPalHttpClient(environment);
    return client;
  }
}
package com.stop.think.shiro.service.paypal;

import com.paypal.http.HttpResponse;
import com.paypal.orders.*;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class PayPalService {

  public HttpResponse<Order> captureOrder(String orderId) throws IOException {
    OrdersCaptureRequest request = new OrdersCaptureRequest(orderId);
    request.requestBody(buildRequestBody());
    //3. Call PayPal to capture an order
    HttpResponse<Order> response = PayPalClient.client().execute(request);
    //4. Save the capture ID to your database. Implement logic to save capture to your database for future reference.
    System.out.println("Status Code: " + response.statusCode());
    System.out.println("Status: " + response.result().status());
    System.out.println("Order ID: " + response.result().id());
    System.out.println("Links: ");
    for (LinkDescription link : response.result().links()) {
      System.out.println("\t" + link.rel() + ": " + link.href());
    }
    System.out.println("Capture ids:");
    for (PurchaseUnit purchaseUnit : response.result().purchaseUnits()) {
      for (Capture capture : purchaseUnit.payments().captures()) {
        System.out.println("\t" + capture.id());
      }
    }
    System.out.println("Buyer: ");
    Payer buyer = response.result().payer();
    System.out.println("\tEmail Address: " + buyer.email());
    System.out.println("\tName: " + buyer.name().fullName());
    return response;
  }

  /**
   *Creating empty body for capture request.
   *You can set the payment source if required.
   *
   *@return OrderRequest request with empty body
   */
  public OrderRequest buildRequestBody() {
    return new OrderRequest();
  }
}
package com.stop.think.shiro.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.paypal.http.HttpResponse;
import com.paypal.orders.*;
import com.stop.think.shiro.common.PayPalConfig;
import com.stop.think.shiro.dao.OrderRecordDao;
import com.stop.think.shiro.dao.entity.OrderRecord;
import com.stop.think.shiro.service.paypal.PayPalClient;
import com.stop.think.shiro.service.paypal.PayPalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class OrderRecordService {

    @Resource private OrderRecordDao orderRecordDao;
    @Resource private PayPalService payPalService;

    @Value("${domain.url}")
    private String domainUrl;

    public JSONObject createPayOrder() {
        OrderRecord record = new OrderRecord();
        record.setId(IdUtil.getSnowflake().nextIdStr());
        record.setCreateDate(LocalDateTime.now());
        record.setName("测试商铺");
        record.setMoney(BigDecimal.ONE);
        record.setCurrencyCode("USD"); // 币种
        record.setStatus(OrderRecord.STATUS_ING);
        JSONObject retJson = new JSONObject();
        try {
            retJson.set("approveUrl", this.createPayPalOrder(record));
        } catch (IOException e) {
            log.error("创建订单错误", e);
            // 这个地方也可以进行重试
        }
        orderRecordDao.save(record);
        return retJson;
    }

    private String createPayPalOrder(OrderRecord orderRecord) throws IOException {
        OrdersCreateRequest request = new OrdersCreateRequest();
        request.prefer("return=representation");
        request.requestBody(buildRequestBody(orderRecord));
        //3. Call PayPal to set up a transaction
        HttpResponse<Order> response = PayPalClient.client().execute(request);
        String approveUrl = "";
        if (response.statusCode() == 201) {
            System.out.println("Status Code: " + response.statusCode());
            System.out.println("Status: " + response.result().status());
            System.out.println("Order ID: " + response.result().id());
            System.out.println("Links: ");
            // 保存支付订单号
            orderRecord.setPayOrdNo(response.result().id());
            for (LinkDescription link : response.result().links()) {
                System.out.println("\t" + link.rel() + ": " + link.href() + "\tCall Type: " + link.method());
                if (link.rel().equals("approve")) {
                    approveUrl = link.href();
                }
            }
            System.out.println("Total Amount: " + response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode()
                    + " " + response.result().purchaseUnits().get(0).amountWithBreakdown().value());
        }
        return approveUrl;
    }

    private OrderRequest buildRequestBody(OrderRecord orderRecord) {
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.checkoutPaymentIntent(PayPalConfig.INTENT);

        ApplicationContext context = new ApplicationContext()
                // 商家名称,展示在支付界面
                .brandName(PayPalConfig.BRAND_NAME)
                .landingPage(PayPalConfig.LANDING_PAGE)
                .cancelUrl(domainUrl + "/pay/result") // 取消返回地址
                .returnUrl(domainUrl + "/pay/result") // 支付成功返回地址
                .userAction(PayPalConfig.USER_ACTION)
                .shippingPreference(PayPalConfig.SHIPPING_PREFERENCE);
        orderRequest.applicationContext(context);

        List<PurchaseUnitRequest> purchaseUnitRequests = new ArrayList<PurchaseUnitRequest>();
        PurchaseUnitRequest unitRequest = new PurchaseUnitRequest()
                .customId(orderRecord.getId() + "")
                // 发票标识
                .invoiceId(orderRecord.getId() + "")
                .amountWithBreakdown(
                        new AmountWithBreakdown()
                                .currencyCode("USD")
                                .value(NumberUtil.decimalFormat("###.00", orderRecord.getMoney()))
                );
        purchaseUnitRequests.add(unitRequest);
        orderRequest.purchaseUnits(purchaseUnitRequests);
        return orderRequest;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean payNotify(String payOrdNo, boolean cancelFlag) {
        if (StrUtil.isBlank(payOrdNo)) {
            return false;
        }
        Optional<OrderRecord> orderRecordOptional = orderRecordDao.findByPayOrdNo(payOrdNo);
        if (!orderRecordOptional.isPresent()) {
            log.warn("单号错误:" + payOrdNo);
            return false;
        }
        OrderRecord record = orderRecordOptional.get();
        if (!record.getStatus().equals(OrderRecord.STATUS_ING)) {
            return true;
        }
        if (cancelFlag) {
            record.setPayDate(LocalDateTime.now());
            record.setMark("取消支付");
            orderRecordDao.save(record);
            return false;
        }
        try {
            // 核销资金
            payPalService.captureOrder(payOrdNo);
        } catch (IOException e) {
            log.error("支付核销失败:" + payOrdNo, e);
            return false;
        }
        record.setPayDate(LocalDateTime.now());
        record.setMark("");
        record.setStatus(OrderRecord.STATUS_SUC);
        orderRecordDao.save(record);
        return true;
    }
}

web.controller

package com.stop.think.shiro.web.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.stop.think.shiro.service.OrderRecordService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/pay")
public class PayPalController {

    @Resource private OrderRecordService orderRecordService;

    @GetMapping("/auth_url")
    public JSONObject createAuthUrl() {
        return orderRecordService.createPayOrder();
    }

    @GetMapping("/result")
    public JSONObject frontReturn(String token, String PayerID) {
        // 同步返回时
        boolean paySuccess = orderRecordService.payNotify(token, StrUtil.isBlank(PayerID));
        JSONObject retJson = new JSONObject();
        retJson.set("payResult", paySuccess);
        return retJson;
    }
}
package com.stop.think.shiro;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

application.yml

server:
  context-path: ''
  port: 8093
spring:
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
    username: sa
    password: sa
    validationQuery: SELECT 1 FROM DUAL
  http:
    encoding:
      force: true
  jackson:
    defaultPropertyInclusion: NON_NULL
  jpa:
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        connection:
          CharSet: utf8mb4
          characterEncoding: utf8mb4
          useUnicode: true
        format_sql: true
    show-sql: true

# paypal 支付配置
paypal:
  client:
    id:
    secret:
  brand:
    name: 测试商家

# domain
domain:
  url: http://localhost:8093

# 环境配置
is:
  test: true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值