PayPal - ExpressCheckout和定期付款

问题描述:

我正试图让PayPal的ExpressCheckout与定期付款合作。我有前两个阶段(对SetExpressCheckout和GetExpressCheckoutDetails的调用),但CreateRecurringPaymentsProfile失败,错误如下。我使用Paypal示例代码的修改版本,但我怀疑我(不)设置编码器值。任何人都使用过这个?PayPal - ExpressCheckout和定期付款

错误:

// TIMESTAMP: 2010-10-27T09:57:47Z 
// CORRELATIONID: ad2b2da33c672 
// ACK: Failure 
// VERSION: 51.0 
// BUILD: 1553277 
// L_ERRORCODE0: 11502 
// L_SHORTMESSAGE0: Invalid Token 
// L_LONGMESSAGE0: The token is invalid 
// L_SEVERITYCODE0: Error 

我正在使用的代码是:

/// This returns true 
public bool SetExpressCheckout(string amt, ref string token, ref string retMsg) 
{ 
    string host = "www.paypal.com"; 
    if (bSandbox) { 
     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp"; 
     host = "www.sandbox.paypal.com"; 
    } 

    string baseUrl = "http://" + HttpContext.Current.Request.Url.Authority; 
    string[] returnUrlParts = WebConfigurationManager.AppSettings["PaypalReturnUrl"].Split('?'), 
      cancelUrlParts = WebConfigurationManager.AppSettings["PaypalCancelUrl"].Split('?'); 
    string returnURL = baseUrl + VirtualPathUtility.ToAbsolute(returnUrlParts[0]) + (returnUrlParts.Length > 1 ? '?' + returnUrlParts.Skip(1).Aggregate((itms, itm) => itms + itm) : string.Empty), 
      cancelURL = baseUrl + VirtualPathUtility.ToAbsolute(cancelUrlParts[0]) + (cancelUrlParts.Length > 1 ? '?' + cancelUrlParts.Skip(1).Aggregate((itms, itm) => itms + itm) : string.Empty); 

    NVPCodec encoder = new NVPCodec(); 
    encoder["METHOD"] = "SetExpressCheckout"; 
    encoder["RETURNURL"] = returnURL; 
    encoder["CANCELURL"] = cancelURL; 
    encoder["AMT"] = amt; 
    //encoder["PAYMENTACTION"] = "SALE"; 
    encoder["CURRENCYCODE"] = "GBP"; 
    encoder["NOSHIPPING"] = "1"; 
    encoder["L_BILLINGTYPE0"] = "RecurringPayments"; 
    encoder["L_BILLINGAGREEMENTDESCRIPTION0"] = "Subscription for MySite"; 

    string pStrrequestforNvp = encoder.Encode(); 
    string pStresponsenvp = HttpCall(pStrrequestforNvp); 

    NVPCodec decoder = new NVPCodec(); 
    decoder.Decode(pStresponsenvp); 

    string strAck = decoder["ACK"].ToLower(); 
    if (strAck != null && (strAck == "success" || strAck == "successwithwarning")) { 
     token = decoder["TOKEN"]; 
     string ECURL = "https://" + host + "/cgi-bin/webscr?cmd=_express-checkout" + "&token=" + token; 
     retMsg = ECURL; 
     return true; 
    } else { 
     retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" + 
      "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" + 
      "Desc2=" + decoder["L_LONGMESSAGE0"]; 
     return false; 
    } 
} 

/// This returns true 
public bool GetExpressCheckoutDetails(string token, ref string PayerId, ref string retMsg) 
{ 
    if (bSandbox) { 
     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp"; 
    } 
    NVPCodec encoder = new NVPCodec(); 
    encoder["METHOD"] = "GetExpressCheckoutDetails"; 
    encoder["TOKEN"] = token; 

    string pStrrequestforNvp = encoder.Encode(); 
    string pStresponsenvp = HttpCall(pStrrequestforNvp); 

    NVPCodec decoder = new NVPCodec(); 
    decoder.Decode(pStresponsenvp); 

    string strAck = decoder["ACK"].ToLower(); 
    if (strAck != null && (strAck == "success" || strAck == "successwithwarning")) { 
     return true; 
    } else { 
     retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" + 
      "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" + 
      "Desc2=" + decoder["L_LONGMESSAGE0"]; 
     return false; 
    } 
} 

// This fails and returns false with the following in the decoder result 
// TIMESTAMP: 2010-10-27T09:57:47Z 
// CORRELATIONID: ad2b2da33c672 
// ACK: Failure 
// VERSION: 51.0 
// BUILD: 1553277 
// L_ERRORCODE0: 11502 
// L_SHORTMESSAGE0: Invalid Token 
// L_LONGMESSAGE0: The token is invalid 
// L_SEVERITYCODE0: Error 
public bool CreateRecurringPaymentsProfileCode(string token, string amount, string profileDate, string billingPeriod, string billingFrequency, ref string retMsg) 
{ 
    NVPCallerServices caller = new NVPCallerServices(); 
    IAPIProfile profile = ProfileFactory.createSignatureAPIProfile(); 
    profile.APIUsername = this.APIUsername; 
    profile.APIPassword = this.APIPassword; 
    profile.APISignature = this.APISignature; 
    profile.Environment = "sandbox"; 
    caller.APIProfile = profile; 
    string host = "www.paypal.com"; 
    if (bSandbox) { 
     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp"; 
     host = "www.sandbox.paypal.com"; 
    } 

    NVPCodec encoder = new NVPCodec(); 
    encoder["VERSION"] = "51.0"; 

    // Add request-specific fields to the request. 
    encoder["METHOD"] = "CreateRecurringPaymentsProfile"; 
    encoder["TOKEN"] = token; 
    encoder["AMT"] = amount; 
    encoder["PROFILESTARTDATE"] = profileDate; //Date format from server expects Ex: 2006-9-6T0:0:0 
    encoder["BILLINGPERIOD"] = billingPeriod; 
    encoder["BILLINGFREQUENCY"] = billingFrequency; 
    encoder["L_BILLINGTYPE0"] = "RecurringPayments"; 
    encoder["DESC"] = "Subscription for MySite"; 

    // Execute the API operation and obtain the response. 
    string pStrrequestforNvp = encoder.Encode(); 
    string pStresponsenvp = caller.Call(pStrrequestforNvp); 

    NVPCodec decoder = new NVPCodec(); 
    decoder.Decode(pStresponsenvp); 
    //return decoder["ACK"]; 
    string strAck = decoder["ACK"]; 
    bool success = false; 
    if (strAck != null && (strAck == "Success" || strAck == "SuccessWithWarning")) { 
     success = true; // check decoder["result"] 
    } else { 
     success = false; 
    } 

    StringBuilder buffer = new StringBuilder(); 
    for (int i = 0; i < decoder.Keys.Count; i++) { 
     buffer.AppendFormat("{0}: {1}", decoder.Keys[i], decoder.GetValues(i).Aggregate((vals, val) => vals + "----" + val)); 
    } 
    retMsg = buffer.ToString(); 

    return success;// returns false 
} 

如果有帮助,这是调用它的代码是:

NVPAPICaller ppapi = new NVPAPICaller(); 
NVPCodec decoder = new NVPCodec(); 
string retMsg = string.Empty, 
     token = Convert.ToString(Session["token"]), 
     finalPaymentAmount = "15", 
     payerId = Convert.ToString(Session["payerId"] ?? string.Empty); // set from SetExpressCheckout 

bool shippingSuccess = ppapi.GetExpressCheckoutDetails(token, ref payerId, ref retMsg); 
if (shippingSuccess) { 
    payerId = Session["payerId"].ToString(); 
    btnConfirm.Enabled = false; 
    bool paymentSuccess = ppapi.CreateRecurringPaymentsProfileCode(token, finalPaymentAmount, DateTime.Now.ToString("yyyy-M-DTH:m:s"), "Year", "1", ref retMsg); 
    // but paymentSuccess is false 

这是实际上最终的日期,但它让我永远注意到。在致电CreateRecurringPaymentsProfile, encoder["PROFILESTARTDATE"] = profileDate;是错误的。我需要时使用yyyy-MM-DDTHH:mm:ss格式yyyy-MM-ddTHH:mm:ss (lowercase d's).

我有同样的错误,但它是由于没有重定向到PayPal,然后使用PayPal后重定向到我的网站。