Here's what I'm designing a site where multiple shops my be able to offer their producs to sale. Every seller will have a virtual store on my site. I'm using paypal for purchase operations. I've considered to allow customers to use credit card without having a paypal account, and I'm trying to use Adaptive payments flow to allow "buy as guest" flow. I'm trying to use paypal default flow (not the rest api) since I don't want to be worried about handling credit card data and having to design my site as PCI compliant.
So with this escenario here's what I'm using:
- From this site https://developer.paypal.com/webapps/developer/docs/classic/adaptive-payments/integration-guide/APIntro/ I'm trying to implement the payment flow specified on the section
Setting Up Web Pages to Invoke the Embedded Payment Flow Using a Lightbox
- Since this payment flow requires a pay key to be generated, I'm using the code found on this link:
https://github.com/paypal/rest-api-sdk-dotnet/tree/master/Samples/RestApiSample
-So on my MVC I have a page that generates the order, and it calls a Helper methods to get the paykey. Here's the most relevant one:
public static string GetPayKey(DummyPurchase purchase)
{
ReceiverList receiverList = new ReceiverList();
receiverList.receiver = new List<Receiver>();
//(Required) Amount to be paid to the receiver
string[] amt = new string[1] { purchase.TotalPrice.ToString() };
// Receiver's email address. This address can be unregistered with paypal.com.
// If so, a receiver cannot claim the payment until a PayPal account is linked
// to the email address. The PayRequest must pass either an email address or a phone number.
// Maximum length: 127 characters
string[] receiverEmail = new string[1] { purchase.StoreId.ToString() };
string cancelUrl = ConfigurationHelper<string>.GetKeyValue(Constants.PAYPAL_CANCEL_URL);
string returnUrl = ConfigurationHelper<string>.GetKeyValue(Constants.PAYPAL_RETURN_URL);
string currency = ConfigurationHelper<string>.GetKeyValue(Constants.PAYPAL_CURRENCY_CODE);
//Generate Receivers list
for (int i = 0; i < amt.Length; i++)
{
Receiver rec = new Receiver(Convert.ToDecimal(amt[i]));
if (receiverEmail[i] != string.Empty)
{
rec.email = receiverEmail[i];
}
receiverList.receiver.Add(rec);
}
PayRequest request = new PayRequest(new RequestEnvelope("en_US"), "PAY",
cancelUrl, currency,
receiverList, returnUrl);
//call the service
AdaptivePaymentsService service = null;
PayResponse response = null;
try
{
// (https://github.com/paypal/sdk-core-dotnet/wiki/SDK-Configuration-Parameters)
Dictionary<string, string> configurationMap = GetAcctAndConfig();
// Creating service wrapper object to make an API call and loading
// configuration map for your credentials and endpoint
service = new AdaptivePaymentsService(configurationMap);
response = service.Pay(request);
}
catch (Exception ex)
{
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(ex));
return "";
}
Dictionary<string, string> responseValues = new Dictionary<string, string>();
string redirectUrl = null;
if (!(response.responseEnvelope.ack == AckCode.FAILURE) &&
!(response.responseEnvelope.ack == AckCode.FAILUREWITHWARNING))
{
return response.payKey;
}
return "";
}
-After I get this key, I get the html from another view that has the form as the API guide specifies, having the paykey string as the model for this view.
@model string
<h2>ConfirmCheckout</h2>
<script src="https://www.paypalobjects.com/js/external/dg.js">
</script>
<form action="https://www.paypal.com/webapps/adaptivepayment/flow/pay"
target="PPDGFrame">
<input id="type" type="hidden" name="expType" value="light">
<input id="paykey" type="hidden" name="paykey" value="@Model">
<input type="submit" id="submitBtn" value="Pay with PayPal">
</form>
-After the view is rendered, I call the javascript code to start the flow:
var dgFlow = new PAYPAL.apps.DGFlow({ trigger: 'submitBtn' });
-The flow works perfectly and I get a valid pay key rendered on this form. But when I click this button (submit button on form with paykey) I get 2 different errors. This is the most frequent one:
This transaction has already been approved. Please visit your PayPal Account Overview to see the details.
-But sometimes I get a "Your payment session has expired" error.
I have 2 questions:
- Does someone know how to fix those errors?
- I'm using clasic API since guest payment flow for adaptive payments require a PayKey to start the flow (in order to avoid security and PCI complience matters). I did not found a method on the Paypal REST API that could get the same PayKey. Is there any method to get those keys?
Thanks a lot