Dans ce tutoriel, je vais vous montrer comment effectuer des paiements à l'aide de l'API REST PayPal et de C#. Toutes les bibliothèques qu'ils proposent pour différents langages comme Ruby, Node.js, Python, PHP, etc. sont très similaires, donc tous les concepts ici sont applicables à toutes les bibliothèques.
Paramètres du projet
Tout d'abord, j'ai créé un projet MVC dans Visual Studio 2015 : Fichier > Nouveau > Projet et sélectionné Application ASP.NET.
Sélectionnez le modèle ASP.NET 5 Web Application, qui utilise le nouveau MVC 6. C'est similaire à MVC 5 si vous le connaissez.
Comme vous pouvez le voir sur la photo ci-dessous, j'ai ajouté quelques fichiers et dossiers à la solution. Les deux principales choses à noter sont :
Dans les Références, j'ai supprimé la cible DNX Core 5.0, qui nous permet d'exécuter ce projet sous Mac OS X ou Linux, mais les bibliothèques PayPal dont nous avons besoin n'ont pas encore été mises à jour.
J'ai ajouté le dossier "Services" dans lequel j'encapsulerai la logique des appels PayPal afin que nous puissions garder le contrôleur simple et clair.
Utilisez NuGet pour installer le SDK PayPal. Cliquez avec le bouton droit sur le nom de la solution et sélectionnez Gérer les packages NuGet, puis recherchez "PayPal" et installez-le.
Créer une application PayPal
Pour intégrer notre application à PayPal, nous devons accéder à PayPal Developers et sous REST API Applications, cliquer sur Create Application.
Nommez votre application et sélectionnez un compte de développeur sandbox à associer à l'application. À des fins de test, nous pouvons accéder à http://sandbox.paypal.com et nous connecter à l'aide des informations de connexion du bac à sable pour afficher un compte PayPal et des transactions de test.
Après avoir cliqué sur Créer une application, nous verrons l'écran de confirmation contenant l'ID client et le jeton secret.
Copiez le jeton clientId et clientSecret dans appsettings.json comme indiqué dans la capture d'écran ci-dessous :
Test de paiement
PayPal fournit un environnement sandbox pour les tests. À partir de là, vous pouvez créer des comptes d’acheteur et de vendeur test. Après votre inscription, vous disposerez d'un compte d'entreprise dans le bac à sable lié à votre compte de développeur.
Pour créer un nouveau compte test, connectez-vous au site Web du développeur, puis cliquez sur l'onglet Panneau de configuration et accédez à Bac à sable > Comptes. Vous pouvez voir la liste des comptes tests (si disponible) ici :
Si vous n'avez pas encore créé de compte test, allez-y et cliquez sur Créer un compte dans le coin supérieur droit pour créer au moins un compte personnel test et un compte professionnel test.
Après avoir créé un compte test, vous pouvez vous connecter via www.sandbox.paypal.com en utilisant l'adresse e-mail de test et le mot de passe que vous avez attribués à chaque compte sur le formulaire précédent. Ceci est utile pour tester si les fonds seront transférés sur votre compte test Business lorsque vous effectuez un achat à l'aide de votre compte test personnel. Vous êtes maintenant prêt à commencer l'intégration avec PayPal et à tester si les fonds sont transférés d'un compte à un autre.
Paiement PayPal unique
PayPal propose différents modes de paiement. Vous pouvez utiliser les paiements directs par carte de crédit, ce qui signifie que vos clients ne peuvent pas voir la page de connexion ou le résumé PayPal – tout se passe sur votre site Web. Pour ce faire, vous devez être conforme à la norme PCI et je vous recommande d'utiliser Stripe car vous n'avez besoin que de SSL en utilisant leur bibliothèque JavaScript. Pour payer via PayPal, en revanche, il y a trois étapes :
Spécifiez les informations de paiement pour créer un paiement.
Obtenir le paiement approuvé, redirigez vos clients vers PayPal pour approuver la transaction.
Une fois que PayPal a redirigé votre client vers votre site Web, Exécutez le paiement pour obtenir les fonds.
Dans le dossier Services de mon projet MVC, j'ai créé la classe PayPalPaymentService et y ai ajouté les méthodes suivantes :
public static Payment CreatePayment(string baseUrl, string intent)
{
// ### Api Context
// Pass in a `APIContext` object to authenticate
// the call and to send a unique request id
// (that ensures idempotency). The SDK generates
// a request id if you do not pass one explicitly.
var apiContext = PayPalConfiguration.GetAPIContext();
// Payment Resource
var payment = new Payment()
{
intent = intent, // `sale` or `authorize`
payer = new Payer() { payment_method = "paypal" },
transactions = GetTransactionsList(),
redirect_urls = GetReturnUrls(baseUrl, intent)
};
// Create a payment using a valid APIContext
var createdPayment = payment.Create(apiContext);
return createdPayment;
}
private static List<Transaction> GetTransactionsList()
{
// A transaction defines the contract of a payment
// what is the payment for and who is fulfilling it.
var transactionList = new List<Transaction>();
// The Payment creation API requires a list of Transaction;
// add the created Transaction to a List
transactionList.Add(new Transaction()
{
description = "Transaction description.",
invoice_number = GetRandomInvoiceNumber(),
amount = new Amount()
{
currency = "USD",
total = "100.00", // Total must be equal to sum of shipping, tax and subtotal.
details = new Details() // Details: Let's you specify details of a payment amount.
{
tax = "15",
shipping = "10",
subtotal = "75"
}
},
item_list = new ItemList()
{
items = new List<Item>()
{
new Item()
{
name = "Item Name",
currency = "USD",
price = "15",
quantity = "5",
sku = "sku"
}
}
}
});
return transactionList;
}
private static RedirectUrls GetReturnUrls(string baseUrl, string intent)
{
var returnUrl = intent == "sale" ? "/Home/PaymentSuccessful" : "/Home/AuthorizeSuccessful";
// Redirect URLS
// These URLs will determine how the user is redirected from PayPal
// once they have either approved or canceled the payment.
return new RedirectUrls()
{
cancel_url = baseUrl + "/Home/PaymentCancelled",
return_url = baseUrl + returnUrl
};
}
public static Payment ExecutePayment(string paymentId, string payerId)
{
// ### Api Context
// Pass in a `APIContext` object to authenticate
// the call and to send a unique request id
// (that ensures idempotency). The SDK generates
// a request id if you do not pass one explicitly.
var apiContext = PayPalConfiguration.GetAPIContext();
var paymentExecution = new PaymentExecution() { payer_id = payerId };
var payment = new Payment() { id = paymentId };
// Execute the payment.
var executedPayment = payment.Execute(apiContext, paymentExecution);
return executedPayment;
}
Copier après la connexion
Certains paramètres sont passés dans cet appel :
Intent : Trois valeurs possibles : "Ventes" pour un paiement immédiat, "Autoriser" pour une autorisation pour capturer le paiement ultérieurement, ou "Commande" pour créer une commande. Lorsque vous êtes autoriséà facturer un paiement plus tard, vous bénéficiez d'une garantie de 3 jours, mais vous pouvez essayer de récupérer le paiement jusqu'à 29 jours plus tard.
Payeur : La source des fonds pour ce paiement, le mode de paiement utilisé - Paiement par portefeuille PayPal, prélèvement bancaire ou carte de crédit directe.
Transaction : Utilisé pour préciser le montant du paiement et éventuellement préciser les éléments à payer. Si vous le souhaitez, vous pouvez également spécifier des sous-totaux, des frais d'expédition et des taxes.
URL de redirection : Précisez l'URL vers laquelle PayPal redirige vos clients après une transaction afin que vous puissiez mettre à jour la base de données et afficher un message de confirmation.
La fonctionnalité précédente peut être utilisée depuis le contrôleur comme indiqué ci-dessous :
public IActionResult CreatePayment()
{
var payment = PayPalPaymentService.CreatePayment(GetBaseUrl(), "sale");
return Redirect(payment.GetApprovalUrl());
}
public IActionResult PaymentCancelled()
{
// TODO: Handle cancelled payment
return RedirectToAction("Error");
}
public IActionResult PaymentSuccessful(string paymentId, string token, string PayerID)
{
// Execute Payment
var payment = PayPalPaymentService.ExecutePayment(paymentId, PayerID);
return View();
}
Copier après la connexion
Comme vous pouvez le constater, j'ai créé trois actions :
CreatePayment : C'est l'action qui déclenche le paiement. Il appelle PayPal pour créer le paiement, puis redirige l'utilisateur vers PayPal pour approuver la transaction.
Paiement réussi : C'est ce que fait PayPal pour rediriger le client après un paiement réussi. À ce stade, nous pouvons exécuter le paiement et transférer les fonds sur notre compte marchand.
PaymentCancelled : redirigez l'utilisateur de PayPal vers cette action s'il annule le processus d'approbation. À ce stade, vous souhaiterez peut-être donner au client la possibilité de réessayer ou de vous contacter.
Autorisez le paiement pour l'obtenir plus tard
Ce scénario est très similaire au cas précédent. Vous souhaiterez peut-être utiliser cette méthode si vous essayez de précommander un produit qui n'est pas encore disponible. Les étapes pour obtenir ce paiement sont :
Autoriser le paiement : Le paramètre "Intention" de cet appel doit être "Autoriser".
Soyez payé : N'oubliez pas que l'autorisation est garantie jusqu'à 3 jours, mais vous pouvez essayer d'être payé jusqu'à 29 jours.
Pour implémenter ce type de paiement, je viens d'ajouter une nouvelle méthode dans la classe PayPalPaymentService pour capturer le paiement :
public static Capture CapturePayment(string paymentId)
{
var apiContext = PayPalConfiguration.GetAPIContext();
var payment = Payment.Get(apiContext, paymentId);
var auth = payment.transactions[0].related_resources[0].authorization;
// Specify an amount to capture. By setting 'is_final_capture' to true, all remaining funds held by the authorization will be released from the funding instrument.
var capture = new Capture()
{
amount = new Amount()
{
currency = "USD",
total = "4.54"
},
is_final_capture = true
};
// Capture an authorized payment by POSTing to
// URI v1/payments/authorization/{authorization_id}/capture
var responseCapture = auth.Capture(apiContext, capture);
return responseCapture;
}
Copier après la connexion
Puis j'ai ajouté deux nouvelles actions dans HomeController pour afficher ce type de paiement :
public IActionResult AuthorizePayment()
{
var payment = PayPalPaymentService.CreatePayment(GetBaseUrl(), "authorize");
return Redirect(payment.GetApprovalUrl());
}
public IActionResult AuthorizeSuccessful(string paymentId, string token, string PayerID)
{
// Capture Payment
var capture = PayPalPaymentService.CapturePayment(paymentId);
return View();
}
Copier après la connexion
AuthorizePayment est l'action qui déclenche le paiement. Elle est très similaire à la fonction précédente "CreatePayment", mais dans ce cas, nous passons "authorize" comme paramètre d'intention.
AuthorizeSuccessful est l'action qui redirigera vos clients après avoir approuvé avec succès un paiement PayPal. À ce stade, je capture le paiement, mais vous pouvez enregistrer le paymentId dans la base de données et capturer le paiement si nécessaire.
Dans ces exemples de code, j'ai codé en dur les valeurs des variables de paiement pour plus de simplicité. Dans votre application réelle, vous les envelopperiez probablement dans une méthode qui prend toutes ces valeurs comme variables afin que tout puisse être défini et réutilisé dynamiquement.
Abonnez-vous
C'est ce qu'on appelle un « plan de facturation » dans PayPal : vous pouvez créer un plan de paiement récurrent et abonner vos clients à un plan de facturation en créant un accord de facturation. À l'aide de l'API PayPal REST, vous pouvez créer, mettre à jour ou supprimer des plans de facturation ; c'est quelque chose que vous pouvez utiliser si vous souhaitez créer un panneau d'administration pour gérer ces éléments pour votre entreprise.
Les étapes pour créer des frais récurrents pour un client sont les suivantes :
Créez un plan de facturation et activez-le. Une fois que vous avez créé un plan de facturation, celui-ci aura le statut « Créé ». Il doit être activé en émettant une requête PATCH.
Créer un accord de règlement et Exécuter : la réponse à l'appel « Créer un accord de règlement » comprend des liens vers approbation_url et exécuter_url. Nous devons obtenir l’approbation de l’accord de facturation, puis exécuter l’accord de facturation.
Plan de facturation
Créer un plan de facturation
Créez des plans de facturation qui définissent les cycles de facturation. Ceci est un résumé des paramètres que nous devons transmettre lors de la création du plan.
// Define the plan and attach the payment definitions and merchant preferences.
// More Information: https://developer.paypal.com/webapps/developer/docs/api/#create-a-plan
var billingPlan = new Plan
{
name = "Tuts+ Plus",
description = "Monthly plan for courses.",
type = "fixed",
// Define the merchant preferences.
// More Information: https://developer.paypal.com/webapps/developer/docs/api/#merchantpreferences-object
merchant_preferences = new MerchantPreferences()
{
setup_fee = GetCurrency("0"), // $0
return_url = "returnURL", // Retrieve from config
cancel_url = "cancelURL", // Retrieve from config
auto_bill_amount = "YES",
initial_fail_amount_action = "CONTINUE",
max_fail_attempts = "0"
},
payment_definitions = new List<PaymentDefinition>
{
// Define a trial plan that will only charge $9.99 for the first
// month. After that, the standard plan will take over for the
// remaining 11 months of the year.
new PaymentDefinition()
{
name = "Trial Plan",
type = "TRIAL",
frequency = "MONTH",
frequency_interval = "1",
amount = GetCurrency("0"), // Free for the 1st month
cycles = "1",
charge_models = new List<ChargeModel>
{
new ChargeModel()
{
type = "TAX",
amount = GetCurrency("1.65") // If we need to charge Tax
},
new ChargeModel()
{
type = "SHIPPING",
amount = GetCurrency("9.99") // If we need to charge for Shipping
}
}
},
// Define the standard payment plan. It will represent a monthly
// plan for $19.99 USD that charges once month for 11 months.
new PaymentDefinition
{
name = "Standard Plan",
type = "REGULAR",
frequency = "MONTH",
frequency_interval = "1",
amount = GetCurrency("15.00"),
// > NOTE: For `IFNINITE` type plans, `cycles` should be 0 for a `REGULAR` `PaymentDefinition` object.
cycles = "11",
charge_models = new List<ChargeModel>
{
new ChargeModel
{
type = "TAX",
amount = GetCurrency("2.47")
},
new ChargeModel()
{
type = "SHIPPING",
amount = GetCurrency("9.99")
}
}
}
}
};
// Get PayPal Config
var apiContext = PayPalConfiguration.GetAPIContext();
// Create Plan
plan.Create(apiContext);
Copier après la connexion
新创建的结算计划处于 CREATED 状态。将其激活为“活动”状态,以便您的客户可以订阅该计划。要激活该计划,我们需要发出 PATCH 请求:
// Activate the plan
var patchRequest = new PatchRequest()
{
new Patch()
{
op = "replace",
path = "/",
value = new Plan() { state = "ACTIVE" }
}
};
plan.Update(apiContext, patchRequest);
Copier après la connexion
如您所见,PayPal 库是其 REST API 的直接包装器,这很好,但与 Stripe 等其他 API 相比,该 API 也非常复杂。因此,将所有 PayPal 通信包装在对象中,为我们的应用程序提供更清晰、更简单的 API,这确实是一个不错的选择。在这里您可以看到封装在多个带有参数的函数中的代码的样子:
public static Plan CreatePlanObject(string planName, string planDescription, string returnUrl, string cancelUrl,
string frequency, int frequencyInterval, decimal planPrice,
decimal shippingAmount = 0, decimal taxPercentage = 0, bool trial = false, int trialLength = 0, decimal trialPrice = 0)
{
// Define the plan and attach the payment definitions and merchant preferences.
// More Information: https://developer.paypal.com/docs/rest/api/payments.billing-plans/
return new Plan
{
name = planName,
description = planDescription,
type = PlanType.Fixed,
// Define the merchant preferences.
// More Information: https://developer.paypal.com/webapps/developer/docs/api/#merchantpreferences-object
merchant_preferences = new MerchantPreferences()
{
setup_fee = GetCurrency("1"),
return_url = returnUrl,
cancel_url = cancelUrl,
auto_bill_amount = "YES",
initial_fail_amount_action = "CONTINUE",
max_fail_attempts = "0"
},
payment_definitions = GetPaymentDefinitions(trial, trialLength, trialPrice, frequency, frequencyInterval, planPrice, shippingAmount, taxPercentage)
};
}
private static List<PaymentDefinition> GetPaymentDefinitions(bool trial, int trialLength, decimal trialPrice,
string frequency, int frequencyInterval, decimal planPrice, decimal shippingAmount, decimal taxPercentage)
{
var paymentDefinitions = new List<PaymentDefinition>();
if (trial)
{
// Define a trial plan that will charge 'trialPrice' for 'trialLength'
// After that, the standard plan will take over.
paymentDefinitions.Add(
new PaymentDefinition()
{
name = "Trial",
type = "TRIAL",
frequency = frequency,
frequency_interval = frequencyInterval.ToString(),
amount = GetCurrency(trialPrice.ToString()),
cycles = trialLength.ToString(),
charge_models = GetChargeModels(trialPrice, shippingAmount, taxPercentage)
});
}
// Define the standard payment plan. It will represent a 'frequency' (monthly, etc)
// plan for 'planPrice' that charges 'planPrice' (once a month) for #cycles.
var regularPayment = new PaymentDefinition
{
name = "Standard Plan",
type = "REGULAR",
frequency = frequency,
frequency_interval = frequencyInterval.ToString(),
amount = GetCurrency(planPrice.ToString()),
// > NOTE: For `IFNINITE` type plans, `cycles` should be 0 for a `REGULAR` `PaymentDefinition` object.
cycles = "11",
charge_models = GetChargeModels(trialPrice, shippingAmount, taxPercentage)
};
paymentDefinitions.Add(regularPayment);
return paymentDefinitions;
}
private static List<ChargeModel> GetChargeModels(decimal planPrice, decimal shippingAmount, decimal taxPercentage)
{
// Create the Billing Plan
var chargeModels = new List<ChargeModel>();
if (shippingAmount > 0)
{
chargeModels.Add(new ChargeModel()
{
type = "SHIPPING",
amount = GetCurrency(shippingAmount.ToString())
});
}
if (taxPercentage > 0)
{
chargeModels.Add(new ChargeModel()
{
type = "TAX",
amount = GetCurrency(String.Format("{0:f2}", planPrice * taxPercentage / 100))
});
}
return chargeModels;
}
Copier après la connexion
更新结算计划
您可以通过提出“PATCH”请求来更新现有结算方案的信息。这是一个包装该调用的函数:
public static void UpdateBillingPlan(string planId, string path, object value)
{
// PayPal Authentication tokens
var apiContext = PayPalConfiguration.GetAPIContext();
// Retrieve Plan
var plan = Plan.Get(apiContext, planId);
// Activate the plan
var patchRequest = new PatchRequest()
{
new Patch()
{
op = "replace",
path = path,
value = value
}
};
plan.Update(apiContext, patchRequest);
}
Copier après la connexion
要更新计费计划描述,我们可以调用此函数并传递正确的参数:
UpdateBillingPlan(
planId: "P-5FY40070P6526045UHFWUVEI",
path: "/",
value: new Plan { description = "new description" });
public static void ExecuteBillingAgreement(string token)
{
// PayPal Authentication tokens
var apiContext = PayPalConfiguration.GetAPIContext();
var agreement = new Agreement() { token = token };
var executedAgreement = agreement.Execute(apiContext);
}
Copier après la connexion
暂停计费协议
使用此方法暂停协议:
public static void SuspendBillingAgreement(string agreementId)
{
var apiContext = PayPalConfiguration.GetAPIContext();
var agreement = new Agreement() { id = agreementId };
agreement.Suspend(apiContext, new AgreementStateDescriptor()
{ note = "Suspending the agreement" });
}
Copier après la connexion
重新激活计费协议
这个与上一个非常相似:
public static void ReactivateBillingAgreement(string agreementId)
{
var apiContext = PayPalConfiguration.GetAPIContext();
var agreement = new Agreement() { id = agreementId };
agreement.ReActivate(apiContext, new AgreementStateDescriptor()
{ note = "Reactivating the agreement" });
}
Copier après la connexion
取消计费协议
使用此功能取消计划:
public static void CancelBillingAgreement(string agreementId)
{
var apiContext = PayPalConfiguration.GetAPIContext();
var agreement = new Agreement() { id = agreementId };
agreement.Cancel(apiContext, new AgreementStateDescriptor()
{ note = "Cancelling the agreement" });
}
这是人们用来与 PayPal 集成的最常用功能的概述。他们的 API 比本文中解释的集成方法要大得多 - 您还可以发放退款和部分退款,并且他们针对本文涵盖的示例中的边缘情况提供了许多不同的选项。如果您有兴趣获得有关任何特定集成的更多详细信息,请在评论中留下建议。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...
Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.
JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.
Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...
La discussion sur la réalisation des effets de défilement de parallaxe et d'animation des éléments dans cet article explorera comment réaliser le site officiel de Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ...
Apprendre JavaScript n'est pas difficile, mais c'est difficile. 1) Comprendre les concepts de base tels que les variables, les types de données, les fonctions, etc. 2) Master la programmation asynchrone et les implémenter via des boucles d'événements. 3) Utilisez les opérations DOM et promettez de gérer les demandes asynchrones. 4) Évitez les erreurs courantes et utilisez des techniques de débogage. 5) Optimiser les performances et suivre les meilleures pratiques.
Explorez la mise en œuvre de la fonction de glisser et de réglage du panneau de type VScode dans le frontal. Dans le développement frontal, comment implémenter un VScode comme ...
Discussion approfondie des causes profondes de la différence de sortie Console.log. Cet article analysera les différences dans les résultats de sortie de la fonction Console.log dans un morceau de code et expliquera les raisons derrière. � ...