Paypal:L_ERRORCODE0:10401 订单总额无效且参数无效

Posted

技术标签:

【中文标题】Paypal:L_ERRORCODE0:10401 订单总额无效且参数无效【英文标题】:Paypal: L_ERRORCODE0:10401 Order total is invalid and invalid argument 【发布时间】:2012-09-10 09:07:38 【问题描述】:

我跟随https://www.paypal-labs.com/integrationwizard/ecpaypal/main.php 在我的应用程序中实现了paypal 沙盒帐户。我的代码跨越 3 个 jsp 页面,例如 index.jsp -> expresscheckout.jsp -> paypalfunctions.jsp。

expresscheckout.jsp

<%@ include file="paypalfunctions.jsp"%>
<%
    String paymentAmount = "25";

    String currencyCodeType = "USD";
    String paymentType = "Sale";



    String returnURL = "http://2.appid.appspot.com/sucess.jsp";

    String cancelURL = "http://2.appid.appspot.com/canceled.jsp";


    HashMap nvp = CallShortcutExpressCheckout(paymentAmount,
            currencyCodeType, paymentType, returnURL, cancelURL,
            session);
    String strAck = nvp.get("ACK").toString();
    if (strAck != null && strAck.equalsIgnoreCase("Success")) 
        //' Redirect to paypal.com
        RedirectURL(nvp.get("TOKEN").toString(), response);
     else 


        String ErrorCode = nvp.get("L_ERRORCODE0").toString();
        String ErrorShortMsg = nvp.get("L_SHORTMESSAGE0").toString();
        String ErrorLongMsg = nvp.get("L_LONGMESSAGE0").toString();
        String ErrorSeverityCode = nvp.get("L_SEVERITYCODE0")
                .toString();
    
%>

paypalfunctions.jsp 如下:

<%

    gv_APIUserName  = "myid_78955666_biz_api1.gmail.com";
    gv_APIPassword  = "1347856389";
    gv_APISignature = "AFcWxV21C7fd0v3bYYYRCps-s-rl31AuP4KrN6UABOJ1fGdNRYoIpc.qjr";

    //BN Code is only applicable for partners
    gv_BNCode       = "PP-ECWizard"; 

    boolean bSandbox = true;



    if (bSandbox == true)
    
        gv_APIEndpoint = "https://api-3t.sandbox.paypal.com/nvp";
        PAYPAL_URL = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=";
    
    else
    
        gv_APIEndpoint = "https://api-3t.paypal.com/nvp";
        PAYPAL_URL = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=";
     

    String HTTPREQUEST_PROXYSETTING_SERVER = "";
    String HTTPREQUEST_PROXYSETTING_PORT = "";
    boolean USE_PROXY = false;

    gv_Version  = "2.3";

    //WinObjHttp Request proxy settings.
    gv_ProxyServer  = HTTPREQUEST_PROXYSETTING_SERVER;
    gv_ProxyServerPort = HTTPREQUEST_PROXYSETTING_PORT;
    gv_Proxy        = 2;    //'setting for proxy activation
    gv_UseProxy     = USE_PROXY;


%>

<%!

    String gv_APIEndpoint;
    String gv_APIUserName;
    String gv_APIPassword;
    String gv_APISignature;
    String gv_BNCode;

    String gv_Version;
    String gv_nvpHeader;
    String gv_ProxyServer;  
    String gv_ProxyServerPort; 
    int gv_Proxy;
    boolean gv_UseProxy;
    String PAYPAL_URL;

    public HashMap CallShortcutExpressCheckout( String paymentAmount, String currencyCodeType, String paymentType, 
                                                String returnURL, String cancelURL,
                                                HttpSession session)
    

        session.setAttribute("paymentType", paymentType);
        session.setAttribute("currencyCodeType", currencyCodeType);
ored in $nvpstr
        */
        String nvpstr = "&Amt=25&PAYMENTACTION=" + paymentType + "&ReturnUrl=" + URLEncoder.encode( returnURL ) + "&CANCELURL=" + URLEncoder.encode( cancelURL ) + "&CURRENCYCODE=" + currencyCodeType;

        /* 
        Make the call to PayPal to get the Express Checkout token
        If the API call succeded, then redirect the buyer to PayPal
        to begin to authorize payment.  If an error occured, show the
        resulting errors
        */

        HashMap nvp = httpcall("SetExpressCheckout", nvpstr);
        String strAck = nvp.get("ACK").toString();
        session.setAttribute("nvpstr", nvpstr);
        session.setAttribute("strAck", strAck);
        if(strAck !=null && strAck.equalsIgnoreCase("Success"))
        
            session.setAttribute("TOKEN", nvp.get("TOKEN").toString());
        

        return nvp;
    

    public HashMap CallMarkExpressCheckout( String paymentAmount, String currencyCodeType, String paymentType, String returnURL, 
                                String cancelURL, String shipToName, String shipToStreet, String shipToCity, String shipToState,
                                String shipToCountryCode, String shipToZip, String shipToStreet2, String phoneNum,
                                HttpSession session)
    

        session.setAttribute("paymentType", paymentType);
        session.setAttribute("currencyCodeType", currencyCodeType);

        String nvpStr = "ADDROVERRIDE=1&Amt=" + paymentAmount + "&PAYMENTACTION=" + paymentType;
        nvpStr = nvpStr + "&CURRENCYCODE=" + currencyCodeType + "&ReturnUrl=" + URLEncoder.encode( returnURL ) + "&CANCELURL=" + URLEncoder.encode( cancelURL );
        nvpStr = nvpStr + "&SHIPTONAME=" + shipToName + "&SHIPTOSTREET=" + shipToStreet + "&SHIPTOSTREET2=" + shipToStreet2;
        nvpStr = nvpStr + "&SHIPTOCITY=" + shipToCity + "&SHIPTOSTATE=" + shipToState + "&SHIPTOCOUNTRYCODE=" + shipToCountryCode;
        nvpStr = nvpStr + "&SHIPTOZIP=" + shipToZip + "&PHONENUM" + phoneNum;


        HashMap nvp = httpcall("SetExpressCheckout", nvpStr);//made a change from original code
        String strAck = nvp.get("ACK").toString();
        if(strAck !=null && (strAck.equalsIgnoreCase("Success") || strAck.equalsIgnoreCase("SuccessWithWarning")))
        
            session.setAttribute("TOKEN", nvp.get("TOKEN").toString());
                   
        return nvp;
    

    public HashMap GetShippingDetails( String token, HttpSession session)
    


        String nvpstr= "&TOKEN=" + token;


        HashMap nvp = httpcall("GetExpressCheckoutDetails", nvpstr);
        String strAck = nvp.get("ACK").toString();
        if(strAck !=null && (strAck.equalsIgnoreCase("Success") || strAck.equalsIgnoreCase("SuccessWithWarning")))
        
            session.setAttribute("PAYERID", nvp.get("PAYERID").toString());
                   
        return nvp;
    

    public HashMap ConfirmPayment( String finalPaymentAmount, HttpSession session, HttpServletRequest request)
    

        String token            =  session.getAttribute("TOKEN").toString();
        String currencyCodeType =  session.getAttribute("currencyCodeType").toString();
        String paymentType      =  session.getAttribute("paymentType").toString();
        String payerID          =  session.getAttribute("PAYERID").toString();
        String serverName       =  request.getServerName();

        String nvpstr  = "&TOKEN=" + token + "&PAYERID=" + payerID + "&PAYMENTACTION=" + paymentType + "&AMT=" + finalPaymentAmount;
        nvpstr = nvpstr + "&CURRENCYCODE=" + currencyCodeType + "&IPADDRESS=" + serverName;

        HashMap nvp = httpcall("DoExpressCheckoutPayment", nvpstr);

        return nvp;
    


    HashMap DirectPayment ( String paymentType, String paymentAmount,
                        String creditCardType, String creditCardNumber, String expDate, String cvv2,
                        String firstName, String lastName, String street, String city, String state, String zip, String countryCode,
                        String currencyCode, String IPAddress)
    
        String nvpStr = "Amt=" + paymentAmount + "&PAYMENTACTION=" + paymentType;
        nvpStr += "&IPADDRESS=" + IPAddress;
        nvpStr += "&CREDITCARDTYPE=" + creditCardType + "&ACCT=" + creditCardNumber + "&EXPDATE=" + expDate + "&CVV2=" + cvv2;
        nvpStr += "&FIRSTNAME=" + firstName + "&LASTNAME=" + lastName + "&STREET=" + street + "&CITY=" + city + "&STATE=" + state + "&COUNTRYCODE=" + countryCode + "&ZIP=" + zip;
        nvpStr += "&CURRENCYCODE=" + currencyCode;

        return httpcall("DoDirectPayment", nvpStr);
    

    public HashMap httpcall( String methodName, String nvpStr)
    

        String version = "2.3";
        String agent = "Mozilla/4.0";
        String respText = "";
        HashMap nvp=null;


        String encodedData = "METHOD=" + methodName + "&VERSION=" + gv_Version + "&PWD=" + gv_APIPassword + "&USER=" + gv_APIUserName + "&SIGNATURE=" + gv_APISignature + nvpStr + "&BUTTONSOURCE=" + gv_BNCode;

        try 
        
            URL postURL = new URL( gv_APIEndpoint );
            HttpURLConnection conn = (HttpURLConnection)postURL.openConnection();

            // Set connection parameters. We need to perform input and output, 
            // so set both as true. 
            conn.setDoInput (true);
            conn.setDoOutput (true);

            // Set the content type we are POSTing. We impersonate it as 
            // encoded form data 
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty( "User-Agent", agent );

            //conn.setRequestProperty( "Content-Type", type );
            conn.setRequestProperty( "Content-Length", String.valueOf( encodedData.length()) );
            conn.setRequestMethod("POST");

            // get the output stream to POST to. 
            DataOutputStream output = new DataOutputStream( conn.getOutputStream());
            output.writeBytes( encodedData );
            output.flush();
            output.close ();

            // Read input from the input stream.
            DataInputStream  in = new DataInputStream (conn.getInputStream()); 
            int rc = conn.getResponseCode();
            if ( rc != -1)
            
                BufferedReader is = new BufferedReader(new InputStreamReader( conn.getInputStream()));
                String _line = null;
                while(((_line = is.readLine()) !=null))
                
                    respText = respText + _line;
                           
                nvp = deformatNVP( respText );
            
            return nvp;
        
        catch( IOException e )
        
            // handle the error here
            return null;
        
    

    public HashMap deformatNVP( String pPayload )
    
        HashMap nvp = new HashMap(); 
        StringTokenizer stTok = new StringTokenizer( pPayload, "&");
        while (stTok.hasMoreTokens())
        
            StringTokenizer stInternalTokenizer = new StringTokenizer( stTok.nextToken(), "=");
            if (stInternalTokenizer.countTokens() == 2)
            
                String key = URLDecoder.decode( stInternalTokenizer.nextToken());
                String value = URLDecoder.decode( stInternalTokenizer.nextToken());
                nvp.put( key.toUpperCase(), value );
            
        
        return nvp;
    

    public void RedirectURL( String token, HttpServletResponse response )
    
        String payPalURL = PAYPAL_URL + token; 

        //response.sendRedirect( payPalURL );
        response.setStatus(302);
        response.setHeader( "Location", payPalURL );
        response.setHeader( "Connection", "close" );
           

%>

当我点击快速结帐时,它会重定向到 https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=EC-9CY1483461514290L 。 但是在“您的订单摘要”中,没有显示当前的购买金额。 同样在使用我的买家帐户登录并确认地址和付款后,我的 success.jsp 页面中会显示以下错误消息:

时间戳:2012-09-18T06:07:32Z 相关 ID:b4fe3695b410a 确认:失败 版本:84.0 建造:3622349 L_ERRORCODE0:10401 L_SHORTMESSAGE0:由于参数无效,交易被拒绝。有关详细信息,请参阅其他错误消息。 L_LONGMESSAGE0:订单总数无效。 L_SEVERITYCODE0:错误

但是当我打印我的名称-值-对(nvp)时,它包含金额

NVPSTR===>&Amt=25&PAYMENTACTION=Sale&ReturnUrl=http%3A%2F%2F2.appid.appspot.com%2Fsucess.jsp&CANCELURL=http%3A%2F%2F2.appid.appspot.com%2Fcanceled .jsp&CURRENCYCODE=USD

请解决或提出解决方案。

【问题讨论】:

【参考方案1】:

您必须在 DoExpressCheckoutPayment API 调用和 SetExpressCheckout API 调用中提交金额。目前,您不会同时为您的 SetEC 和 DoEC 提交金额,而只是为您的 SetEC 提交金额。 (如果你没有为 SetEC 设置它,你永远不会得到一个令牌。)

您的 DoEC 调用应该与您的 SetEC 调用几乎相同,只是您不需要 RETURNURL 和 CANCELURL。

此外,除非您提交交易的订单项详细信息,否则金额不会显示在订单摘要中:

L_PAYMENTREQUEST_0_NAME0=Books 
L_PAYMENTREQUEST_0_AMT0=154.00 
L_PAYMENTREQUEST_0_NUMBER0=ABC123 
L_PAYMENTREQUEST_0_QTY0=2 
L_PAYMENTREQUEST_0_NAME1=CDs 
L_PAYMENTREQUEST_0_AMT1=50.00 
L_PAYMENTREQUEST_0_NUMBER1=BY-Z4736 
L_PAYMENTREQUEST_0_QTY1=3 
PAYMENTREQUEST_0_ITEMAMT=458.00 
PAYMENTREQUEST_0_SHIPPINGAMT=20.00 
PAYMENTREQUEST_0_TAXAMT=46.20 
PAYMENTREQUEST_0_AMT=524.20 

【讨论】:

以上是关于Paypal:L_ERRORCODE0:10401 订单总额无效且参数无效的主要内容,如果未能解决你的问题,请参考以下文章

PayPal Pro 设置错误 10548

Paypal 沙盒 - 无效的商家配置错误 10501?

PayPal API 直接付款流程

Paypal 错误:不支持商户国家/地区

Express Checkout Paypal 失败

PayPal NVP API - 获取快速结帐令牌