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

PayPal REST API没有执行付款。无法将付款对象的状态从“已创建”更改为“已审核”或“已完成”

闻人志
2023-03-14
Payment payment = new Payment();
payment.setIntent("sale");
payment.setPayer(payer);
payment.setTransactions(transactions);
payment.setRedirectUrls(redirectUrls);
Payment createdPayment = payment.create(apiContext);
if (link.getRel().equalsIgnoreCase("approval_url")) 
{
         req.setAttribute("redirectURL", link.getHref());
         resp.sendRedirect(link.getHref());
}
String authToken=req.getParameter("token");
String paymentID=req.getParameter("paymentID");
Payment approvedPayment=Payment.getPaymentObject(authToken,paymentID);
String authToken=req.getParameter("token");
String paymentID=req.getParameter("payerID");
Payment approvedPayment=Payment.get(authToken,payerID);

如果有人能告诉我,我的推理出了什么问题,那就太棒了。谢谢!下面是我的主servlet页面中的完整代码。注意,returnURL将您带回到同一个页面,在该页面中,它发现了包含在来自payPal的HTTP请求中的payerID,并正确地输入了主if-else语句的“if”块,这生成了一些完全没有帮助的基本输出。还要注意,我已经将一些基本函数调用外包给了其他类,如AccessToken类。

public class PaymentInfoServlet2 extends HttpServlet {

    private static final long serialVersionUID = 1L;

   // private static final Logger LOGGER = Logger
     //               .getLogger(PaymentWithPayPalServlet.class);
    Map<String, String> map = new HashMap<String, String>();

    public void init(ServletConfig servletConfig) throws ServletException {
            // ##Load Configuration
            // Load SDK configuration for
            // the resource. This intialization code can be
            // done as Init Servlet.
            InputStream is = PaymentInfoServlet2.class
                            .getResourceAsStream("/sdk_config.properties");
            try {
                    PayPalResource.initConfig(is);
            } catch (PayPalRESTException e) {
                  //  LOGGER.fatal(e.getMessage());
            }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
            doPost(req, resp);
    }

    // ##Create
    // Sample showing to create a Payment using PayPal
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                    throws ServletException, IOException {
            // ###AccessToken
            // Retrieve the access token from
            // OAuthTokenCredential by passing in
            // ClientID and ClientSecret
            APIContext apiContext = null;
            String accessToken = null;
            try {
                AccessToken access=new AccessToken(PublicUtils.getUser(),PublicUtils.getPass(),req,resp);

                    accessToken = access.getToken();

                    // ### Api Context
                    // Pass in a `ApiContext` object to authenticate
                    // the call and to send a unique request id
                    // (that ensures idempotency). The SDK generates
                    // a request id if you do not pass one explicitly.
                    apiContext = access.getContext();
                    // Use this variant if you want to pass in a request id
                    // that is meaningful in your application, ideally
                    // a order id.
                    /*
                     * String requestId = Long.toString(System.nanoTime(); APIContext
                     * apiContext = new APIContext(accessToken, requestId ));
                     */
            } catch (Exception e) {
                    req.setAttribute("error", e.getMessage());
            }
            if (req.getParameter("PayerID") != null) {
                    Payment payment = new Payment();
                    if (req.getParameter("guid") != null) {
                            payment.setId(map.get(req.getParameter("guid")));
                    }

                    PaymentExecution paymentExecution = new PaymentExecution();
                    paymentExecution.setPayerId(req.getParameter("PayerID"));
                    try {
                            payment.execute(apiContext, paymentExecution);
                            req.setAttribute("response", Payment.getLastResponse());
                    } catch (PayPalRESTException e) {
                            req.setAttribute("error", e.getMessage());
                    }
                    PrintWriter out=resp.getWriter();
                    out.println("This is the returnURL page.");
                    out.println("paymentID="+payment.getId());
                    out.println("pamentState="+payment.getState());
                    out.println("executedPayerID="+paymentExecution.getPayerId());
                   // out.println("executedTransaction: "+paymentExecution.getTransactions().get(0).toString());
            } else {

                    // ###Details
                    // Let's you specify details of a payment amount.
                    Details details = new Details();
                    details.setShipping("1");
                    details.setSubtotal("5");
                    details.setTax("1");

                    // ###Amount
                    // Let's you specify a payment amount.
                    Amount amount = new Amount();
                    amount.setCurrency("USD");
                    // Total must be equal to sum of shipping, tax and subtotal.
                    amount.setTotal("7");
                    amount.setDetails(details);

                    // ###Transaction
                    // A transaction defines the contract of a
                    // payment - what is the payment for and who
                    // is fulfilling it. Transaction is created with
                    // a `Payee` and `Amount` types
                    Transaction transaction = new Transaction();
                    transaction.setAmount(amount);
                    transaction
                                    .setDescription("This is the payment transaction description.");

                    // The Payment creation API requires a list of
                    // Transaction; add the created `Transaction`
                    // to a List
                    List<Transaction> transactions = new ArrayList<Transaction>();
                    transactions.add(transaction);

                    // ###Payer
                    // A resource representing a Payer that funds a payment
                    // Payment Method
                    // as 'paypal'
                    Payer payer = new Payer();
                    payer.setPaymentMethod("paypal");

                    // ###Payment
                    // A Payment Resource; create one using
                    // the above types and intent as 'sale'
                    Payment payment = new Payment();
                    payment.setIntent("sale");
                    payment.setPayer(payer);
                    payment.setTransactions(transactions);

                    // ###Redirect URLs
                    RedirectUrls redirectUrls = new RedirectUrls();
                    String guid = UUID.randomUUID().toString().replaceAll("-", "");
                    redirectUrls.setCancelUrl(req.getScheme() + "://"
                                    + req.getServerName() + ":" + req.getServerPort()
                                    + req.getContextPath() + "/CancelServlet?guid=" + guid);
                    redirectUrls.setReturnUrl(req.getScheme() + "://"
                                    + req.getServerName() + ":" + req.getServerPort()
                                    + req.getContextPath() + "/PaymentInfoServlet2?guid=" + guid);
                    payment.setRedirectUrls(redirectUrls);

                    // Create a payment by posting to the APIService
                    // using a valid AccessToken
                    // The return object contains the status;
                    try {
                            Payment createdPayment = payment.create(apiContext);
                         //   LOGGER.info("Created payment with id = "
                           //                 + createdPayment.getId() + " and status = "
                             //               + createdPayment.getState());
                            // ###Payment Approval Url
                            Iterator<Links> links = createdPayment.getLinks().iterator();
                            while (links.hasNext()) {
                                    Links link = links.next();
                                    if (link.getRel().equalsIgnoreCase("approval_url")) {
                                            req.setAttribute("redirectURL", link.getHref());
                                            resp.sendRedirect(link.getHref());
                                    }
                            }
                            req.setAttribute("response", Payment.getLastResponse());
                            map.put(guid, createdPayment.getId());
                    } catch (PayPalRESTException e) {
                            req.setAttribute("error", e.getMessage());
                    }
            }
            req.setAttribute("request", Payment.getLastRequest());
            //req.getRequestDispatcher("response.jsp").forward(req, resp);
    }

}

针对我下面的第一个评论,约扎·卡尔洛夫,我补充了以下内容:

嗯,我想我对此有几个反应。首先,谢谢你。第二,我想我的问题可能是不太清楚。我对如何检索上面名为“Created Payment”的旧支付对象并不感到困惑。在上面复制的完整代码中,我使用了与您引用的完全相同的guid代码。这样做的一个问题是,它除了将createdPayment对象的ID复制到一个新的空白Payment对象之外,什么也不做。新对象的状态仍然是空白的,它的所有其他属性也是空白的。它是一个带有ID的空白对象,仅此而已。几乎是一文不值的,所以我要么遗漏了一些东西,要么示例servlet完全错误。

public class SessionStore {
    public static Map<String, HttpSession> map = new HashMap<String,HttpSession>();
}

and in my main servlet, called PaymentInfoServlet2, here is the relevant code that i execute before the servlet ends and the user is re-directed to the payPal pages:

HttpSession sess=req.getSession();
String sessID=sess.getId();
SessionStore.map.put(sessID, sess);

// append sessID to redirectURLs - the URLs that the payPal pages return back to
approveURL=req.getScheme() + "://"+ req.getServerName() + ":" +req.getServerPort()+ req.getContextPath() +"/ApproveServlet?sessID=" +sess.getId();
cancelURL=req.getScheme() + "://"+ req.getServerName() + ":" + req.getServerPort()+ req.getContextPath() +"/CancelServlet?sessID=" +sess.getId();
redirectUrls.setCancelUrl(cancelURL);
redirectUrls.setReturnUrl(approveURL);
payment.setRedirectUrls(redirectUrls);

// create the payment on the payPal server
Payment createdPayment = payment.create(access.getContext());

//add created Payment object to HttpSession object.
ArrayList<Payment> createdPayments=new ArrayList<Payment>();
createdPayments.add(createdPayment);
sess.setAttribute("createdPayments", createdPayments);

// redirect to payPal pages
Iterator<Links> links = createdPayment.getLinks().iterator();
while (links.hasNext()) 
{
    Links link = links.next();
    if (link.getRel().equalsIgnoreCase("approval_url")) 
    {
            url=link.getHref();
        resp.sendRedirect(url);
    }
}
String sessID=req.getParameter("sessID");
HttpSession sess=SessionStore.map.get(sessID);
ArrayList<Payment> cPay=(ArrayList<Payment>)sess.getAttribute("createdPayments");
Payment payment=(Payment)cPay.get(0);

共有1个答案

闻人修明
2023-03-14

你是对的,从PayPal站点页面重定向后,“付款人ID”将被追加为请求参数,而不是付款ID。但您还需要支付id来执行它。这里是贝宝互动工具的代码。

String accessToken = "Bearer Jfdd4h4VrmvLeATBNPsGOpp7pMosTppiy.Jq6xpwQ6E";
APIContext apiContext = new APIContext(accessToken);
apiContext.setConfigurationMap(sdkConfig);

Payment payment = new Payment("PAY-4AL22602580048540KKPBSNY");
PaymentExecution paymentExecute = new PaymentExecuthtml" target="_blank">ion();
paymentExecute.setPayerId("BKJ78SZZ8KJYY");
payment.execute(apiContext, paymentExecute);

所以棘手的部分是如何在请求之间保留付款id,因为正如我们所知,HTTP不持有任何状态。您可以在您提到的示例中看到它是如何实现的:

https://github.com/paypal/rest-api-sdk-java/blob/master/rest-api-sample/src/main/java/com/paypal/api/payments/servlet/paymentwithpaypalservlet.java

String guid = UUID.randomUUID().toString().replaceAll("-", "");
redirectUrls.setReturnUrl(req.getScheme() + "://"
      + req.getServerName() + ":" + req.getServerPort()
      + req.getContextPath() + "/paymentwithpaypal?guid=" + guid);

并将此guid参数与创建的付款id相关联:

map.put(guid, createdPayment.getId());

以便以后使用

payment.setId(map.get(req.getParameter("guid")));

我希望这会有帮助

 类似资料:
  • 我正在使用WooCommerce预订,客户可以要求预订,需要得到管理员的确认。如果管理员不确认预订,我希望订单在24小时后自动取消。 从更改伍兹商务订单状态后X时间已通过回答代码,我正在寻找任何协助,以满足我的要求,使用WP cron。

  • 使用 Stripe 订阅 API,将发出,但它不包含对用于该付款的卡/源的引用。我知道附加到客户的默认源用于订阅发票上的付款,但如果默认源在发票支付和通过 webhook 接收事件之间的时间发生变化,则在我通过 webhook 接收事件时查找默认源将不是确定使用哪个付款源支付该发票的可靠方法。如何获取用于支付发票的来源?如果很重要,这是必要的,以便对成功付款进行与税收相关的操作,因此了解使用了哪张

  • 我WooCommerce,我正在使用“更改管理付款状态返回到WoocommercePending order status unpayed for WoocommercePending”答案代码,当订单状态在后端手动更改为pending时,重置订单的已付款状态。 例如,如果订单状态从“完成”更改为“挂起”,则删除以下内容:“支付日期为4月2日,2019年@5:29 PM” 现在我这里的问题是在订单

  • 我们在PayPal沙箱上测试我们的应用程序。我能够通过一个账户(ewa)付款。tkacz@zoho.com)另一个(ewa.tkacz)-facilitator@mmigroup.pl),并且此付款的状态在付款人帐户(付款ID 3F335538TV000622E)上已完成,但在收款人业务帐户上,我无法看到此付款,也无法通过API获取它。 这个问题是贝宝的,正如你在Stackoverflow论坛上建

  • 问题内容: 我正在使用Spring Data的审计功能,并且具有与此类似的类: 现在,我相信我已经配置好了审核功能,因为当我更新域对象时,可以看到createdBy,createdDate,lastModifiedBy和lastModifiedDate都获得了正确的值。 但是,我的问题是,当我更新对象时,我丢失了createdBy和createdDate的值。因此,当我第一次创建该对象时,我具有所