Enige tijd geleden hebben we nodig om een ​​aankoopsysteem maken via PayPal met als bijzonderheid dat we direct een bevestiging van betaling aan dergelijke aankopen voor de gebruiker weer te geven ontvangen. Dit was het belangrijkste verschil met een winkelwagentje op een website waar je iets fysiek, in dit geval hoeft u niet om de status van een aankoop weten, wanneer het magazijn team om uw bestelling voor te bereiden en te controleren of de betaling is verricht voor het opdienen verkopen . Onze zaak is ingewikkelder. Verkopen diensten die kunnen worden abonnementen, leningen webgebruik, premium diensten, toegang tot prive-ruimtes ... al deze soorten opties voor de gebruiker, na het betalen terug naar uw website om de diensten te genieten die u hebt gekocht.

Als u wilt statische knoppen (Nu kopen) opladen via PayPal hebt twee opties, of maak van de PayPal-website of het genereren van je eigen. Het probleem is dat u moet maken statische creëren een voor elke gebruiker en elke service die u nodig hebt om te verkopen, iets absurd om te proberen en als je had verteld duizenden knoppen. Wanneer u uw eigen degenen kunnen maken normale of veilige, zodat niet kan worden gewijzigd door de manier waarop. Dit is de methode die normaal moeten worden gebruikt, omdat in de normale, een ervaren gebruiker kan het verschuldigde bedrag te wijzigen, iets wat je niet wilt gebeuren.

Voor het systeem goed te werken in een URL moet aankopen gedaan op een manier die zou ons in staat om de gebruiker die maakte de aankoop moesten de betrokken diensten toe te identificeren ontvangt. De oplossing is om de knoppen online ondertekend productidentificatie gebruikt als het userid koopt uw database, zodat bevestigingen aankoop zal de gebruiker die eigenaar is van geven en u voorzien van de diensten waarvoor u heeft betaald creëren. Kan gebruik maken van meer uitgebreide combinaties om het systeem opnieuw te gebruiken voor verschillende producten, bijvoorbeeld-idServicio userid (12345-3). Na ontvangst, om de string te splitsen door het script en hebben alles wat je nodig hebt. In dit geval zijn er verschillende soorten van dienstverlening, maar indentificaban door de kosten ervan, waarbij de gebruikers-id hadden genoeg.

Blijkbaar is eenvoudig, maar ingewikkeld als documentatie, ondanks uitgebreid, is niet helemaal duidelijk. Aan de ene kant is het niet duidelijk hoe het opzetten van uw PayPal-rekening te hebben het hele systeem en de andere is nogal verwarrend hoe de knoppen te maken en ontvangen van bevestigingen. Laten we in detail uitleggen, want het is een interessante oefening in PHP programmeren.

PayPal-account configureren

Het eerste wat je hoeft te doen is het creëren van een X.509-certificaat openbaar , enige systeem dat PayPal accepteert.

De gedetailleerde instructies heb je ze hier . eigenlijk moet je openssl gebruik, elke Linux-systeem, maar het zal hebben geïnstalleerd en Windows-versies.

  1. genrsa openssl-mijn-prvkey.pem 1024
  2. openssl req-new-key mijn-prvkey.pem-x509-days 3650-out my-pubcert.pem

Met deze eerste genereren de private sleutel en vervolgens de X.509-certificaat dat publieke sleutel. Het is belangrijk de-dag, hebben we 10 jaar zetten om problemen te voorkomen. In mijn geval heb ik de eerste 365 dagen als het afkomstig is van het voorbeeld en stopte met werken een jaar zonder je besefte, waren de gebruikers die gewaarschuwd waren. Sla de twee bestanden, mijn-mijn-pubcert.pem prvkey.pem en de behoefte aan hieronder.

We hebben ons certificaat opgesteld. Nu uploaden we naar PayPal te decoderen onze knoppen kennen. In uw PayPal-rekening moet u naar:

Profiel-> Gecodeerde Betaling Instellingen

Van daar, eerst de PayPal publieke certificaat te downloaden, moet u onze knoppen coderen, en aan de andere kant je je publieke certificaat we belde mijn-pubcert.pem uploaden. Je krijgt een certificaat ID te krijgen, datebook.

Als alles goed is gegaan, nu zetten we de rekening te accepteren alleen PayPal-knoppen getekend, zodat niemand kan onze identiteit na te bootsen met knoppen om andere prijzen, een zeer belangrijk detail. We ga dan naar:

Profiel-> Betalingsgegevens website

Actieve Eerste Betaling Data Transfer en kopieën u Identity persoonlijke code die u vertelt, moet je het later. Dan in de Betalingen sectie Gecodeerde Website betaling de optie Blokkeren in de website te activeren is niet versleuteld. Zoals je kunt zien was ik niet zo duidelijk over het proces.

Deze stap is niet vereist, maar daarmee krijgt de gebruiker terug naar uw site nadat u de betaling heeft gedaan en, indien het juist is, en haar diensten ter beschikking te hebben. Maakt Auto-optie terug en geeft de retour-URL, dwz de URL waar uw klant zal worden teruggegeven, bijvoorbeeld: http://www.tudominio.com/index.php?accion=creditos_paypalok

Eindelijk activeer de optie die ons online betalingen kennis. Om dit zullen wij doen:

Profiel-> Preferences Instant Payment Notification

En activeer de kennisgeving van de URL waar we zullen ontvangen, bijvoorbeeld, http://www.tudominio.com/secure/paypal/ipn.php.

Als je dit punt hebt bereikt, heb je alles wat je nodig hebt om te beginnen met de code. Ter herinnering, moet je:

  • Uw private sleutel, mijn-prvkey.pem.
  • Uw publiek certificaat, mijn-pubcert.pem.
  • Uw gecertificeerde ID PayPal
  • Uw persoonlijke code Identity
  • Paypal Public Certificate, paypal_cert_pem.txt.

Wij zijn dus drie taken:

  • Maak knoppen aankoop
  • Maak het script van collecties receptie
  • Maak het script terug na een aankoop

Het creëren van de knoppen

We beginnen met de code. De enige vereiste is dat uw installatie zou hebben geconfigureerd PHP openssl extensie essentieel om te werken met certificaten. Met deze klasse vond ik op het moment (ik had een harde tijd vinden van iets simpels) hebben het hele proces geautomatiseerd, alleen maar zorgen te maken over de gegevens aan dat we hebben gespaard, certificaten en een gecertificeerde ID PayPal, eenvoudig is het niet?.

  1. "Class.PayPalEWP.php" ) ; include ("Class.PayPalEWP.php");
  2. PayPalEWP ( ) ; $ Paypal = & new PayPalEWP ();
  3. ( "/tmp" ) ; $ Paypal -> setTempFileDirectory ("/ tmp");
  4. ( "my-pubcert.pem" , "my-prvkey.pem" ) ; $ Paypal -> SetCertificate ("my-pubcert.pem", "mijn-prvkey.pem");
  5. ( "XXXXXXXXXX" ) ; $ Paypal -> setCertificateID ("XXXXXXXXXX");
  6. ( "paypal_cert_pem.txt" ) ; $ Paypal -> setPayPalCertificate ("paypal_cert_pem.txt");
  7. ( $ PaypalParam = matrix (
  8. , 'Cmd' => '_xclick'
  9. , 'Business' => 'info@tudominio.com'
  10. 'Item_name' => 'Buy Dienst X,
  11. idUsuario '], 'Item_number' => $ _SESSION ['userid'],
  12. 5 ', 'Bedrag' => 'Mei',
  13. 1 ', 'No_shipping' => '1 ',
  14. EUR ', 'Currency_code' => 'EUR',
  15. ES ', 'Lc' => 'NL',
  16. );
  17. post \” > $ Form5 = "<form method= action= \" \" bericht https://www.paypal.com/cgi-bin/webscr \" \">
  18. cmd \” value= \” _s-xclick \” /> type = <input verborgen \" \" \" value= name= \" \" _s-xclick cmd \" />
  19. encrypted \” value= \” —–BEGIN PKCS7—– \n ".$paypal->encryptButton($paypalParam)." \n —–END PKCS7—– \” /> \ "Type = \" <input name= verborgen gecodeerd \" PKCS7-- --BEGIN \" \n value= ".$paypal-> \ "encryptButton ($ paypalParam)." \ N - EINDE PKCS7 - \ "/>
  20. <Input > betalingen met PayPal is snel, gratis en veilig \ "style = \" border:. 0; \ ">
  21. </ Form> ";

De code is vrij duidelijk.
We hebben het, $ form5 bevat de code van uw knop.
De belangrijkste parameters zijn:

  • item_name: informatief, zodat uw klant weet wat je koopt. Bijvoorbeeld: Nieuws abonnement aankoop.
  • item_number: Hier stellen we de userid van uw klanten in uw database, zodat u weet wie koopt.
  • hoeveelheid: De prijs die u in rekening brengen, in dit geval 5 euro.

Wijzig deze en andere parameters om uw keuzes reflecteren en aanpassen aan uw toepassing. Door het nemen van $ form5 code op uw site hebben het systeem klaar voor de verkoop.

Het ontvangen van meldingen

Het ontvangen van meldingen is de hoeksteen van het systeem om ervoor te zorgen dat een klant heeft betaald voor een dienst. PayPal heeft gedacht dat je zou kunnen hebben connectiviteit tijdelijk problamas voorkomen dat u een aankoop doet, die vereist dat u bevestigen dat u de bevestiging heeft ontvangen door toezending dezelfde parameters je gestuurd herkennen. Een nieuwsgierige maar effectieve systeem, kun je niet imiteren als geen bewerking identifiers weet u verzendt, zodat alleen de ontvanger de ontvangst bevestiging kan bevestigen. Wat wij doen is het creëren van een HTTP POST-aanvraag met alle parameters naar ons en geef het terug aan PayPal. Als alles goed gaat zullen we ontvangen een GECONTROLEERD en we accepteren deze transactie als geldig en doe de verwerking wij passend achten, te beginnen met controle dubbelhartigheid van de transactie, omdat PayPal zou worden terug te zenden en eindigt bij de dienst waarvoor u heeft betaald waardoor de gebruiker .

  1. / / Lees de post van PayPal-systeem en voeg 'cmd'
  2. ; $ Req = 'cmd = _notify-valideren';
  3. $_POST as $key => $value ) { foreach ($ _POST als $ key => $ value) {
  4. ( stripslashes ( $value ) ) ; $ Waarde = urlencode ( stripslashes ($ value));
  5. ; $ Req = "& $ Key = $ value".;
  6. }
  7. / / Bericht terug naar PayPal-systeem te valideren
  8. " ; $ Header = "POST / cgi-bin/webscr HTTP/1.0 \ r \ n".;
  9. " ; $ Header =. "Content-Type: application / x-www-form-urlencoded \ r \ n";
  10. . strlen ( $req ) . " \r \n \r \n " ; $ Header = "Content-Length:".. strlen . ($ req) "\ r \ n \ r \ n";
  11. ( 'www.paypal.com' , 80 , $errno , $errstr , 30 ) ; $ Fp = fsockopen ('www.paypal.com', 80, $ errno, $ errstr, 30);
  12. / / Wijs geplaatst variabelen om variabelen te plaatsen
  13. [ 'item_name' ] ; $ Item_name = $ _POST ['item_name'];
  14. [ 'item_number' ] ; $ Item_number = $ _POST ['item_number'];
  15. [ 'payment_status' ] ; $ Payment_status = $ _POST ['payment_status'];
  16. [ 'mc_gross' ] ; $ Payment_amount = $ _POST ['mc_gross'];
  17. [ 'mc_currency' ] ; $ Payment_currency = $ _POST ['mc_currency'];
  18. [ 'txn_id' ] ; $ Txn_id = $ _POST ['txn_id'];
  19. [ 'receiver_email' ] ; $ Receiver_email = $ _POST ['receiver_email'];
  20. [ 'payer_email' ] ; $ Payer_email = $ _POST ['payer_email'];
  21. [ 'txn_id' ] ; $ TransID = $ _POST ['txn_id'];
  22. [ 'item_number' ] ; $ Userid = $ _POST ['item_number'];
  23. [ 'mc_gross' ] ; $ Bedrag = $ _POST ['mc_gross'];
  24. ; $ Credits = 100;
  25. ! $fp ) { if (! $ fp) {
  26. / / CONTROL FOUT-GEEN VERBINDING MET PAYPAL
  27. / / GEEN ERNSTIGE, ALS NIET bevestiging van de transactie
  28. / / Opnieuw ZELF DE ONDERSTAANDE
  29. { Else {}
  30. $fp , $header . $req ) ; fputs ($ fp, $ header $ req.);
  31. ! feof ( $fp ) ) { terwijl (! feof ($ fp)) {
  32. ( $fp , 1024 ) ; $ Res = fgets ($ fp, 1024);
  33. strcmp ( $res , "VERIFIED" ) == 0 ) { if ( strcmp ($ res, "GECONTROLEERD") == 0) {
  34. / / Controleer het niet is verwerkt en de transactie
  35. ; $ Query = "SELECT * FROM paypal waar TransID = '$ TransID' en status = 1";
  36. -> Execute ( $query ) ; $ R = $ conn -> Uitvoeren ($ query);
  37. -> recordcount ( ) ; $ Add = $ rs -> recordcount ();
  38. $sumar == 0 ) { if ($ add == 0) {
  39. / / ALLE TRANSACTIE logeamos
  40. . serialize ( $_GET ) . " \r \n POST: " . serialize ( $_POST ) . "" ; . $ Vars = "GET" serialize . ($ _GET) "\ r \ n POST:". serialize ($ _POST) "";.
  41. $ Query = "insert into paypal (TransID, datum, status variabelen)
  42. VALUES ('$ TransID', nu (), 1, '$ vars') ";
  43. -> Execute ( $query ) ; $ R = $ conn -> Uitvoeren ($ query);
  44. / / Hier nu doe je je bewerkingen
  45. Userid: / / Om de service gebruiker toekennen
  46. / / Controleer of geldig userid
  47. { Else {}
  48. / / DUPLICATE TRANSACTIE, NIETS DOEN
  49. }
  50. ( strcmp ( $res , "INVALID" ) == 0 ) { } Else if ( strcmp ($ res, "ONGELDIG") == 0) {
  51. / / FOUT CONTROL
  52. }
  53. }
  54. $fp ) ; fclose ($ fp);
  55. }

We hebben de bevestiging van de betaling van PayPal ontvangen, hebben wij in onze database opgeslagen en we naar onze klantenservice hebben gegeven, zal dit proces verschillend voor elke toepassing te zijn dus niet uit te leggen, doe jouwe als je nodig denkt. Wat ik zou aanraden is om een tabel van alle transacties ontvangen als een logboek bij te houden, helpt u fouten of klachten van gebruikers te vinden.

Merk op dat alleen PayPal lanceert dit proces met de juiste transacties, die beweerd goed, nooit met de verkeerde (gebrek aan evenwicht, verkeerde kaart, etc..).

Terugkerende gebruikers op onze website

Zodra de gebruiker klaar is de PayPal transactie moet het terug te sturen naar onze site, zodat u kunt beginnen met de dienst waarvoor u heeft betaald. Deze methode biedt ons PayPal Automatische terugkeer naar de gebruiker te sturen naar de URL die u hebt opgegeven met vermelding van de parameters van de transactie, inclusief de vraag of het nog geldig was of niet. PayPal is ook aan alles gedacht: ik kan een gebruiker niet terug te keren naar de plaats van herkomst zonder eerst melding gemaakt van het succes van de transactie (de vorige stap). Dus het mechanisme van de PayPal-gebruiker vertraging doorsturen van een paar seconden om te proberen om uw server te maken en op de hoogte van die transactie. Gewoon geweldig. Gebruik nu uw persoonlijke identificatiecode die we hebben verkregen voor het opzetten van het account op PayPal. Is de parameter die we noemen $ auth_token code.

Het proces is vergelijkbaar met de bevestiging van transacties. We moeten communiceren met PayPal dat we de terugkeer verzoek van de gebruiker heeft ontvangen en het is ons, die, alleen dan zal ons de gegevens van de transactie te geven. Weer een merkwaardige methode. Om dit te doen, krijgen we aangegeven door de identificatie van de transactie en moet het terug samen met onze identiteit token door een ander gesprek HTTP POST, dus zorgen we ervoor dat we die informatie vragen. Als alles correct is PayPal brengt ons terug naar de transactiegegevens in reactie op deze oproep. Weer geweldig systeem.

Waarom niet doen zoals in de vorige stap? Eenvoudige, IPN methode is transparantie voor de gebruiker, is een interne oproep naar PayPal systemen om de jouwe te maken, zal niemand weten dat gegevens worden verzonden, zodat u kunt deze gegevens gebruiken om de transactie te bevestigen. En el método de retroceso, esta URL llega al usuario, con lo que podría hacer cosas que no deseamos con los datos, con lo que no nos envían nada en la solicitud, simplemente el identificador de la transacción para que internamente nosotros pidamos los datos validándonos con el código personal .

  1. //read the post from PayPal system and add 'cmd'
  2. $tx_token = $_GET [ 'tx' ] ;
  3. $auth_token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ;
  4. $req = 'cmd=_notify-synch' ;
  5. $req .= "&tx=$tx_token&at=$auth_token" ;
  6. $header .= "POST /cgi-bin/webscr HTTP/1.0 \r \n " ;
  7. $header .= "Content-Type: application/x-www-form-urlencoded \r \n " ;
  8. $header .= "Content-Length: " . strlen ( $req ) . " \r \n \r \n " ;
  9. ( 'www.paypal.com' , 80 , $errno , $errstr , 30 ) ; $ Fp = fsockopen ('www.paypal.com', 80, $ errno, $ errstr, 30);
  10. ; $ IsError = 0;
  11. if ( ! $fp ) {
  12. $isError = 2 ; //error HTTP
  13. } else {
  14. fputs ( $fp , $header . $req ) ;
  15. // read the body data
  16. $res = ;
  17. $headerdone = false ;
  18. while ( ! feof ( $fp ) ) {
  19. $line = fgets ( $fp , 1024 ) ;
  20. if ( strcmp ( $line , " \r \n " ) == 0 ) {
  21. // read the header
  22. $headerdone = true ;
  23. } else if ( $headerdone ) {
  24. // header has been read. now read the contents
  25. $res .= $line ;
  26. }
  27. } // parse the data
  28. $lines = explode ( " \n " , $res ) ;
  29. ( ) ; $ Keyarray = matrix ();
  30. strcmp ( $lines [ 0 ] , "SUCCESS" ) == 0 ) { if ( strcmp ($ lines [0], "SUCCESS") == 0) {
  31. $i = 1 ; $i <count ( $lines ) ; $i ++ ) { for ($ i = 1; $ i <count ($ lijnen); $ i + +) {
  32. $key , $val ) = explode ( "=" , $lines [ $i ] ) ; list ($ key, $ val) = explode ("=", $ regels [$ i]);
  33. urldecode ( $key ) ] = urldecode ( $val ) ; $ Keyarray [ urldecode ($ key)] = urldecode ($ val);
  34. }
  35. ; //no error $ IsError = 0, / / geen fouten
  36. [ 'first_name' ] . " " . $keyarray [ 'last_name' ] ; $ Naam = $ keyarray ['voornaam'] "'$ Keyarray. [' Achternaam '].;
  37. [ 'item_name' ] ; $ Product = $ keyarray ['item_name'];
  38. [ 'payment_gross' ] ; $ Bedrag = $ keyarray ['payment_gross'];
  39. [ 'item_number' ] ; $ Userid = $ keyarray ['item_number'];
  40. + $keyarray [ 'mc_gross' ] ; $ Bedrag = 0 + $ keyarray ['mc_gross'];
  41. $estado = $keyarray [ 'payment_status' ] ;
  42. $transid = $keyarray [ 'txn_id' ] ;
  43. //ahora ya puedes evaluar lo que necesites de tu transacción
  44. //y termina informando al usuario de que todo ha ido bien y ya tiene su servicio
  45. } else if ( strcmp ( $lines [ 0 ] , "FAIL" ) == 0 ) {
  46. $isError = 1 ; //error de transaccion
  47. }
  48. }
  49. fclose ( $fp ) ;

La respuesta que recibimos es una respuesta HTTP estandar, con lo cual debemos ser conscientes de que vamos a recibir primero todas las cabeceras HTTP de la respuesta, después dos saltos de línea ya continuación la respuesta propiamente dicha. En una petición normal esta respuesta sería el código HTML de tu página, pero en este caso recibimos la lista de parámetros de la transacción, uno por línea y del tipo:

 parámetro1=valor1
parámetro2=valor2
 ... 

El código tiene esto en cuenta y, al recoger la respuesta, regenera la lista de parámetros/valores recibidos con lo que tenemos los datos necesarios.
La primera línea va a ser SUCESS ó FAIL , está claro el dato, una indica que la transacción ha sido válida y la otra que no. Obviamente debes informar al usuario de que la operación ha sido correcta y que ya tiene su servicio disponible.

Si has entendido bien todo lo explicado hasta ahora, verás que los sistemas de recepción de notificaciones y retroceso automático son muy similares, de hecho puedes utilizar este último para validar las transacciones de igual modo que con el primero y no necesitarías éste. Pero ¿qué ocurriría si sólo implementas el segundo y el usuario cierra la ventana del pago mientras está en esos segundos de espera antes de reenviarlo a tu web? Simplemente que el usuario no tendría su servicio disponible ya que nunca ha llegado a realizar el proceso del Retroceso automático . Para solucionarlo implementamos los dos. Con el primero aseguramos que la mayoría de transacciones válidas son procesadas y los servicios otorgados al cliente, con la segunda, además de informar al cliente del éxito o fracaso se su operación, tenemos un sistema de redundancia por si el primer procedimiento hubiese fallado. Como en ámbos tenemos el identificador de transacción, simplemente debemos comprobar que esa transacción ya existe y no hacer nada o procesarla si no existe.

Y eso es todo amigos. Con esto hemos aprendido a tener un sistema de compras de servicios seguro y dinámico en PayPal. Cómo habéis podido observar, el procedimiento es bastante complejo en cuanto a configuración y desarrollo, pero es muy interesante el estudio del resultado para tener una idea más amplia de como implementar sistemas seguros.