【问题标题】:Recurring subscription by paypal express checkout, buyer is paid two time通过贝宝快速结账定期订阅,买家支付两次
【发布时间】:2016-01-04 06:32:27
【问题描述】:

我在我的网站上创建了每月订阅的定期付款。用户每个月都会付钱。但我看到买方为订阅支付了两次费用,一次用于启动,一次用于重复。 我读过https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/,我们可以在此设置 PAYMENTREQUEST_n_AMT = 0 并设置 SetExpressCheckout 以忽略发起付款。但是当我将其设置为 0 时,我会收到 amout 为零的错误,因此我可以完成结帐。 我怎样才能创建重复而无需支付两次。我尝试跳过 DoExpressCheckoutPayment 方法,但是通过这种方式,我无法获取交易 ID

【问题讨论】:

  • 你是在设置初始金额吗,我也实现了循环支付,我没有遇到过这样的问题
  • 不,我没有在我的 CreateRecurringPaymentProfile 方法中设置 INITAMT。这是我在 SetExpressCheckout 中传递的参数
  • 下面是 DoExpressCheckoutPayment 中的参数 $fields = array( 'TOKEN' => $checkoutDetails['TOKEN'], 'PAYMENTACTION' => 'Sale', 'PAYERID' => $checkoutDetails['PAYERID '], 'PAYMENTREQUEST_0_AMT' => '5.0', 'PAYMENTREQUEST_0_CURRENCYCODE' => 'NOK' );并创建配置文件 $fields = array( 'TOKEN'=>urlencode($checkoutDetails['TOKEN']), 'PAYERID' => urlencode($checkoutDetails['PAYERID']), 'PROFILESTARTDATE' => time(), ' DESC' => '测试', 'BILLINGPERIOD' => '月', 'BILLINGFREQUENCY' => '1', 'TOTALBILLINGCYCLES'=> '60', 'AMT' => '5.0', 'CURRENCYCODE'=> '挪威克朗');

标签: express paypal checkout recurring


【解决方案1】:

当您创建定期付款时,您可以选择向用户收取两次费用 - 一次与 INITAMT 参数相关,并且会立即从用户帐户中收取费用。其次与 BILLINGPERIOD、BILLINGFREQUENCY、TOTALBILLINGCYCLES 和 REGULARTOTALBILLINGCYCLES 贝宝参数有关,这与当前时间段AFTER的定期付款有关。关键是在循环周期后设置付款并设置 INITAMT 以立即获得第一笔付款

对于(PHP)示例:

$padata['BILLINGPERIOD']                    = 'Month';
$padata['BILLINGFREQUENCY']                 = '1';
$padata['TOTALBILLINGCYCLES']               = '12';
$padata['REGULARTOTALBILLINGCYCLES']        = '1';
$padata['INITAMT']                          = 'MONTHLY PRICE';

在定期付款中,没有交易 ID,但现有订阅 ID 在您的情况下,此键将为 PROFILEID + CORRELATIONID

【讨论】:

  • 对不起,我想立即为第一个循环周期收费。但我不想为启动收费。如果我设置了INITAMT,这意味着买家需要支付2次费用?
  • 在这种情况下必须像我的例子一样设置paypal参数
  • 我试过了,看到买家像这样被收取了 2 次费用pasteboard.co/1c2htGOT.png 但我希望它只收取一次费用。对不起,如果我误解了您的评论。
  • 我跳过了 DoExpressCheckoutPayment 并将参数添加为您的评论,它有效。但是如果忽略 DoExpressCheckoutPayments 方法,你知道如何获取交易 id 吗?
  • 尝试使用paypal方法GetExpressCheckoutDetails
【解决方案2】:

以下是我的应用程序代码,首先我调用的是setExpressCheckout(),而不是getExpressCheckoutDetails()

比使用这段代码支付和生成配置文件收到令牌时

if(request.getParameter("token")!= null && request.getParameter("PayerID") != null){
            if(token.contentEquals(request.getParameter("token"))/* && payerID.contentEquals(request.getParameter("PayerID"))*/){
                this.payerID = request.getParameter("PayerID");

                if(doExpressCheckout()){
                    if(createRecurringProfile()){
                        //some notification showing successful order
                        log.debug("Trasaction status : Successfull");
                        license.setProfileID(profileID);
                        license.setActive(true);
                        license.setLicenseType(LicenseBean.PAYMENT_RECURRING);
                        ApplicationInstance.getCurrent().fireEvent("SaveLicense", description, license,false);
                        ApplicationInstance.getCurrent().fireEvent("DisplayLicenseDetails", "Success", license,false);
                    }

以下是四种方法

public String setExpressCheckout() {
    NVPEncoder encoder = new NVPEncoder();
    NVPDecoder decoder = new NVPDecoder();

    try
    {           

        encoder.add("VERSION", "86.0");         
        encoder.add("METHOD","SetExpressCheckout");
        encoder.add("L_BILLINGTYPE0","RecurringPayments");   
        encoder.add("L_BILLINGAGREEMENTDESCRIPTION0","UserPack");
        // Add request-specific fields to the request string.
        encoder.add("RETURNURL",returnURL);
        encoder.add("CANCELURL",cancelURL); 
        encoder.add("AMT",cost);
        encoder.add("PAYMENTACTION",paymentAction.getValue());
        encoder.add("CURRENCYCODE",currencyCode.getValue());

        // Execute the API operation and obtain the response.
        String NVPRequest= encoder.encode();
        String NVPResponse =caller.call(NVPRequest);
        decoder.decode(NVPResponse);

    } 
    catch(PayPalException pe){
        log.error("Paypal Exception:", pe.getCause());
    }
    catch (Exception ex)
    {
        log.error(ex);
    }
    return decoder.get("TOKEN");
}

public boolean getExpressCheckoutDetails(String token)
{

    NVPEncoder encoder = new NVPEncoder();
    NVPDecoder decoder = new NVPDecoder();

    try
    {
        encoder.add("VERSION", "86.0");
        encoder.add("METHOD", "GetExpressCheckoutDetails");

        // Add request-specific fields to the request string.
        // Pass the token value returned in SetExpressCheckout.
        encoder.add("TOKEN", token);

        // Execute the API operation and obtain the response.
        String NVPRequest = encoder.encode();
        String NVPResponse = caller.call(NVPRequest);
        decoder.decode(NVPResponse);
        //          payerID = decoder.get("PAYERID");
        payerName = decoder.get("PAYERNAME");

    }catch (Exception ex)
    {
        log.error(ex);
    }

    if(decoder.get("ACK").toLowerCase().contains("success")){
        this.token = token;
        return true;
    }
    else{
        return false;
    }
}

public boolean createRecurringProfile() 
{
    NVPEncoder encoder = new NVPEncoder();
    NVPDecoder decoder = new NVPDecoder();

    try
    {
        encoder.add("VERSION", "86.0");
        encoder.add("METHOD","CreateRecurringPaymentsProfile");

        encoder.add("DESC","UserPack");//    #Profile description - same as billing agreement description
        encoder.add("BILLINGPERIOD","Month");//    #Period of time between billings
        encoder.add("BILLINGFREQUENCY","1");//    #Frequency of charges 

        //          encoder.add("INITAMT","25.29");
        //          encoder.add("FAILEDINITAMTACTION","ContinueOnFailure");

        // Add request-specific fields to the request string.
        // Pass the token value by actual value returned in the SetExpressCheckout.
        encoder.add("TOKEN",token);
        encoder.add("PAYERID",payerID);
        Date localTime = new Date(); 
        //creating DateFormat for converting time from local timezone to GMT(as specified in paypal)
        DateFormat converter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        encoder.add("PROFILESTARTDATE",converter.format(localTime));//SimpleDateFormat.getTimeInstance().format(new Date())

        encoder.add("AMT",cost);
        encoder.add("CURRENCYCODE","USD");//    #The currency, e.g. US dollars
        encoder.add("COUNTRYCODE","US");//    #The country code, e.g. US  
        encoder.add("MAXFAILEDPAYMENTS","3");
        //          encoder.add("PAYMENTACTION",paymentAction.getValue());
        encoder.add("CURRENCYCODE",currencyCode.getValue());
        // Execute the API operation and obtain the response.
        String NVPRequest = encoder.encode();
        String NVPResponse =caller.call(NVPRequest);
        decoder.decode(NVPResponse);
        profileID = decoder.get("PROFILEID");
        profileStatus = decoder.get("PROFILESTATUS");
        //transactionID = decoder.get("TRANSACTIONID");
        paymentDate = decoder.get("PAYMENTDATE");
        log.debug("Paypal acknowledgement: "+decoder.get("ACK"));
        //System.out.println("Paypal acknowledgement: "+decoder.get("ACK"));
    } 
    catch(PayPalException pe){
        log.error("Paypal Exception:", pe.getCause());
    }
    catch(Exception ex)
    {
        log.error("Error :",ex.getCause());
    }

    if(decoder.get("ACK").toLowerCase().contains("success")){
        return true;
    }
    else{
        //System.out.println("Paypal error: "+decoder.get("L_SHORTMESSAGE0"));
        log.error("Paypal error: "+decoder.get("L_SHORTMESSAGE0"));
        return false;
    }
}


public boolean doExpressCheckout() 
{
    NVPEncoder encoder = new NVPEncoder();
    NVPDecoder decoder = new NVPDecoder();

    try
    {
        encoder.add("VERSION", "51.0");
        encoder.add("METHOD","DoExpressCheckoutPayment");

        // Add request-specific fields to the request string.
        // Pass the token value by actual value returned in the SetExpressCheckout.
        encoder.add("TOKEN",token);
        encoder.add("PAYERID",payerID);
        encoder.add("AMT",cost);
        encoder.add("PAYMENTACTION",paymentAction.getValue());
        encoder.add("CURRENCYCODE",currencyCode.getValue());
        // Execute the API operation and obtain the response.
        String NVPRequest = encoder.encode();
        String NVPResponse =caller.call(NVPRequest);
        decoder.decode(NVPResponse);
        //transactionID = decoder.get("TRANSACTIONID");
        paymentDate = decoder.get("PAYMENTDATE");
        log.debug("Paypal acknowledgement: "+decoder.get("ACK"));
        //System.out.println("Paypal acknowledgement: "+decoder.get("ACK"));
    } 
    catch(PayPalException pe){
        log.error("Paypal Exception:", pe.getCause());
    }
    catch(Exception ex)
    {
        log.error("Error :",ex.getCause());
    }

    if(decoder.get("ACK").toLowerCase().contains("success")){
        return true;
    }
    else{
        //System.out.println("Paypal error: "+decoder.get("L_SHORTMESSAGE0"));
        log.error("Paypal error: "+decoder.get("L_SHORTMESSAGE0"));
        return false;
    }
}

【讨论】:

    猜你喜欢
    • 2013-09-21
    • 2014-04-09
    • 2015-07-23
    • 2011-09-15
    • 2012-10-13
    • 1970-01-01
    • 2017-07-12
    • 2015-11-03
    相关资源
    最近更新 更多