当前位置: 首页 > 知识库问答 >
问题:

Paypal IPN请求处理与Spring控制器?

赵光赫
2023-03-14

我想扩展一个Spring应用程序的功能,包括一个HTTPendpoint,以接收贝宝即时支付通知。

Paypal在HTTP正文中发送这些内容,如下所示:

MC_Gross=19.95&protection_eligibility=合格&address_status=确认状态s&txn_type=express_checkout&item_name=&mc_currency=usd&item_number=&restence_country=us&test_ipn=1&handling_amount=0.00&transaction_subject=&payment_gross=19.95&shipping=0.00

https://developer.paypal.com/docs/classic/ipn/integration-guide/ipnintro/

我是否需要定义一个具体的类来定义请求体。

请求类

    public class PaypalIPNRequest {

    private static final long serialVersionUID = 1L;
    private String mc_gross;
    private String protection_eligibility;
    private String address_street;
    ...


    public PaypalIPNRequest() {
    }

    //getters setters
}

控制器

@Override
@Auditable
@RequestMapping(value = "/ipnRequest.do", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void ipnRequest(@RequestBody final PaypalIPNRequest request) {
}

正如本文所述,SO答案:@RequestBody和@ResponseBody注释在Spring中

如果贝宝在未来改变他们的IPN请求会发生什么,这会打破吗?

是否有更好的方法在没有特定类的情况下传递请求体?

我可以使用HttpServletRequest吗?

共有1个答案

张高澹
2023-03-14

我过去所做的是使用com.paypal.base.ipn.ipnmessage验证并从请求中检索(如您所建议的)对我来说重要的字段,而不是将整个请求体映射到具体的类,即:

private final static String PAYPAL_WEB_IPN_TXN_PARAM = "txn_id";
private final static String PAYPAL_WEB_IPN_AMOUNT_PARAM = "mc_gross";
private final static String PAYPAL_WEB_IPN_PAYMENT_STATUS_PARAM = "payment_status";
private final static String PAYPAL_WEB_IPN_PAYMENT_STATUS = "Completed";

@Resource(name = "payPalConfigurationMap")
private Map<String, String> configurationMap;

private OAuthTokenCredential oAuthTokenCredential;

@PostConstruct
public void init() {
    Properties properties = new Properties();
    properties.putAll(configurationMap);
    PayPalResource.initConfig(properties);

    oAuthTokenCredential = new OAuthTokenCredential(
            configurationMap.get(Constants.CLIENT_ID),
            configurationMap.get(Constants.CLIENT_SECRET),
            configurationMap
    );
}


public DonationDTO validateWebIPN(HttpServletRequest request) throws Exception {
    IPNMessage ipnlistener = new IPNMessage(request, configurationMap);
    boolean isIpnVerified = ipnlistener.validate();

    String paymentStatus = ipnlistener.getIpnValue(PAYPAL_WEB_IPN_PAYMENT_STATUS_PARAM);

    if (isIpnVerified && paymentStatus.equalsIgnoreCase(PAYPAL_WEB_IPN_PAYMENT_STATUS)) {
        String amount = ipnlistener.getIpnValue(PAYPAL_WEB_IPN_AMOUNT_PARAM);
        String tx = ipnlistener.getIpnValue(PAYPAL_WEB_IPN_TXN_PARAM);

        // irrelevant code

        return donationDTO;
    }else{
        String exceptionMessage = "Problem when requesting info from PayPal service";
        logger.error(exceptionMessage);
        throw new Exception(exceptionMessage);
    }
}

这样,除非Paypal更改了字段的名称(这不应该发生),否则您应该不会有任何问题。

 类似资料:
  • 根据请求主体中的session_type,我必须将请求映射到特定的POJO(JSON->JAVA POJO)。 例如,如果请求正文中的'session_type'是'typeX',那么请求应该映射到ClassX POJO。如果请求正文中的“session_type”是“type y”,那么请求应该映射到ClassY POJO。 如果有一种方法可以使用某种requestbody注释来完成它呢?

  • 频率控制是控制资源利用和保证服务高质量的重要机制。Go可以使用goroutine,channel和ticker来以优雅的方式支持频率控制。 package main import "time" import "fmt" func main() { // 首先我们看下基本的频率限制。假设我们得控制请求频率, // 我们使用一个通道来处理所有的这些请求,这里向requests

  • EasySwoole支持在三个地方进行请求拦截,当一个HTTP请求进来,EasySwoole的执行先后顺序是: Event中的OnRequest事件 自定义路由(可选) 控制器中的OnRequest 在以上任意位置执行 $response->end(),均不会进入下一个流程。 权限验证拦截 例如我现在 /Api/Mobile 下的全部控制器,均需要做权限控制,那幺我们先建立一个全局的抽象控制器。

  • 我的Spring Boot应用程序中有一系列Rest API控制器,其请求映射与某些URL匹配。我需要更改我的实现,以始终确保为所有请求设置特定的自定义标头。如果标头不在那里,我想使请求失败。如果是这样,我想转发到适当的控制器,这将与我当前的实现相同。 有没有办法在Spring Boot做到这一点,而无需修改我现有的控制器呢?我可以尝试使用类似Spring Security的东西吗,即使我的头与安

  • 我用以下方法编写了一个spring控制器来处理回调http请求, 但是我得到错误:由处理程序执行导致的已解决异常:org.springframework.web.HttpMediatypeNotSupportedException:不支持内容类型'application/octet-stream' 我不能更改回调http请求,因为它们来自其他第三方服务,我如何更改控制器以正确获取请求参数?

  • 请求处理 fpm_run()执行后将fork出worker进程,worker进程返回main()中继续向下执行,后面的流程就是worker进程不断accept请求,然后执行PHP脚本并返回。整体流程如下: (1)等待请求: worker进程阻塞在fcgi_accept_request()等待请求; (2)解析请求: fastcgi请求到达后被worker接收,然后开始接收并解析请求数据,直到req