jeudi 14 juillet 2016

Intégrer le paiement Paypal dans un site web en asp.net C#

Les procédures de connexion au serveur Paypal se sont transformées en 2016, voici une procédure simple utilisant les variables API.


1. Dans l'interface Paypal, générer et récupérer les variables de l'API :

Préférences, Paramètres du compte, Mes ventes, Accès à l'API (mettre à jour), Demander les identifiants API.
Récupérer les variables suivantes : UserAPI, PwdAPI, SignatureAPI, toutes trois précédées de codes.PAYPAL_ dans le code qui suit.

2. Dans les deux pages asp.net suivantes ajoutez quatre clauses using :

using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Text;

Dans la page de paiement (ex. paiement.aspx.cs) ajouter ce code (soit dans Page_Load soit dans une autre fonction : Button1_Click) :

string ReturnURL = "http://nomdusite/retour_paiement.aspx"; //adresse complète de redirection en cas de paiement
string CancelURL = ""; //adresse de redirection en cas de défaut de paiement (annulation ou erreur)
string Token = ""; //variable utilisée pour mémoriser le jeton
//Dans l'instruction suivante les variables de l'API sont stockées dans une page de codes nommée codes.cs
//Premier appel au serveur Paypal
StringBuilder postData = new StringBuilder();
postData.Append("METHOD=SetExpressCheckout&");
postData.Append("VERSION=95.0&");
postData.Append("PWD=" + Codes.PAYPAL_PwdAPI + "&");
postData.Append("USER=" + Codes.PAYPAL_UserAPI + "&");
postData.Append("SIGNATURE=" + Codes.PAYPAL_SignatureAPI + "&");
postData.Append("AMT=" + MONTANT.ToString().Replace(",", ".") + "&");
postData.Append("CURRENCYCODE=EUR&");
postData.Append("BRANDNAME=Achat depuis la boutique&");
postData.Append("NOSHIPPING=1&");
postData.Append("SOLUTIONTYPE=sole&");
postData.Append("PAYMENTACTION=Sale&");
postData.Append("RETURNURL=" + ReturnURL + "&");
postData.Append("LANDINGPAGE=billing&");
postData.Append("CANCELURL=" + CancelURL + "&");
WebRequest request = WebRequest.Create("https://api-3t.paypal.com/nvp");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";           
request.ContentLength = postData.ToString().Length;
var sw = new StreamWriter(request.GetRequestStream());
sw.Write(postData.ToString());
sw.Close();
WebResponse response = request.GetResponse();
StreamReader sr = null;
try
{
          //Lecture de la réponse
          sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
          Token += sr.ReadToEnd();
}
catch (Exception ex)
{
           Token = "ERREUR";
           //Mettre un message de retour pour informer l'internaute
}
finally
{
           if (sr != null) sr.Close();
}
try
{
          //Découpage de la chaîne pour récupérer juste le jeton
          Token = Token.Substring(6, Token.IndexOf("&TIME") - 6).Replace("%2d", "-");
          //enregistrement de la commande dans la base de données avec le token

          //Redirection vers le serveur Paypal
          Response.Redirect("https://www.paypal.com/checkoutnow?cmd=_express-checkout&useraction=commit&token=" + Token);
}
catch
{
         //Ne pas mettre d'action ici
}

Dans la page de retour de paiement (retour_paiement.aspx.cs) ajouter ce code dans la fonction Page_Load :

//On récupère les deux variables de la l'URL
string Token = "";
string PayerId = "";
NameValueCollection coll = Request.QueryString;
string[] arr1;
try
{
          arr1 = coll.GetValues("Token");
          Token = arr1[0];
}
catch
{
         Token = "-1";
}
try
{
         arr1 = coll.GetValues("PayerId");
         PayerId = arr1[0];
}
catch
{
         PayerId = "-1";
}        
string Details = "";
//connexion au serveur Paypal pour vérification
StringBuilder postData = new StringBuilder();
postData.Append("METHOD=GetExpressCheckoutDetails&");
postData.Append("VERSION=95.0&");
postData.Append("PWD=" + Codes.PAYPAL_PwdAPI + "&");
postData.Append("USER=" + Codes.PAYPAL_UserAPI + "&");
postData.Append("SIGNATURE=" + Codes.PAYPAL_SignatureAPI + "&");
postData.Append("TOKEN=" + Token + "&");
WebRequest request = WebRequest.Create("https://api-3t.paypal.com/nvp");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.ToString().Length;
var sw = new StreamWriter(request.GetRequestStream());
sw.Write(postData.ToString());
sw.Close();
WebResponse response = request.GetResponse();
StreamReader sr = null;
try
{
          sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
          Details += sr.ReadToEnd();
}
catch (Exception ex)
{
           //Message de retour pour informer d'une erreur d'identification
}
finally
{
          if (sr != null) sr.Close();
}
if (Details.IndexOf("ACK=Success") > -1)
{
          //traitement sur la base de données, récupération du montant de l'opération avec le token
          //Connexion à Paypal pour valider le paiement
         postData = new StringBuilder();
         postData.Append("METHOD=DoExpressCheckoutPayment&");
         postData.Append("VERSION=95.0&");
         postData.Append("PWD=" + Codes.PAYPAL_PwdAPI + "&");
         postData.Append("USER=" + Codes.PAYPAL_UserAPI + "&");
         postData.Append("SIGNATURE=" + Codes.PAYPAL_SignatureAPI + "&");
         postData.Append("PAYERID=" + PayerId + "&");
         postData.Append("CURRENCYCODE=EUR&");
         postData.Append("AMT=" + montant.Replace(",", ".") + "&");
         postData.Append("PAYMENTACTION=Sale&");
         postData.Append("TOKEN=" + Token + "&");
         request = WebRequest.Create("https://api-3t.paypal.com/nvp");
         request.Method = "POST";
         request.ContentType = "application/x-www-form-urlencoded";
         request.ContentLength = postData.ToString().Length;
         sw = new StreamWriter(request.GetRequestStream());
         sw.Write(postData.ToString());
         sw.Close();
          response = request.GetResponse();
          sr = null;
          try
          {
                    sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
                    string Reponse = sr.ReadToEnd();
                    if (Reponse.IndexOf("ACK=Success") > -1)
                    {
                              //Enregistrement du paiement dans la base de données
                             //Retour vers la page de confirmation
                             Response.Redirect("default.aspx?p=1");                    
                }
            }
            catch
            {
                       //Ne pas mettre d'action ici  
            }
}
else
{
          //Message de retour pour informer que le paiement n'a pas été enregistré