⬆️ ⬇️

Paypal connection

In general, they set before me at work the task of organizing the acceptance of payments to our project through Paypal. I was required to give all the necessary data to set up an account (the account itself was configured by another person), well, actually, write a script that will receive data from paypal and charge the money to users.



On Habré I found nothing sensible on this subject. I had to deal with everything myself. Below - the results of these proceedings :)



Types of payments





Paypal allows you to accept several types of payments. Here are some of them:

1. Buy now buttons - a one-time payment to pay for one or several goods (services). Allows you to set the payment amount, description of goods (services), quantity of goods, address, delivery, weight of purchase, etc. The amount of payment you can and do not ask, in this case, Paypal will give the user the opportunity to independently specify the amount he wants to pay.

2. Donate buttons - in principle, the functionality is similar to “Buy now”, also a one-time payment, the amount can be set either forcibly or left to the user's discretion. Otoichie that does not allow you to specify the delivery address and everything connected with it (shipping).

3. Add to cart buttons - allows you to create a basket of your products, on the side of Paypal. On your site, the user can only add products to the cart. To view the contents of the cart or remove any items from there, you will have to log in to Paypal.

4. Subscribe buttons - allows you to organize the reception of periodic payments, for example, payment account, services.

5. Eslt still gift certificates, but did not even try to figure them out.

')

In my case, the ideal solution was the use of “Buy now” payments, which will be discussed further.



You can buy Buy now on your website in two ways:

1. create a button using Paypal's tools.

2. create your own form.



Personally, I used the second option, if only because it allows you to use your own design. Although there are a couple more buns, about them later.



Creating a form of payment





aypal, which naturally, strictly regulates the names of the form fields. A complete list of these fields can be found at cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables . What is used here:

- cmd = _xclick - specify the type of payment “Buy now”;

- business - here we specify email, account where payments will be accepted. The address itself must be confirmed (confirmed somewhere in the account settings);

- item_name - here we set the description of the product / service. Will be displayed in Paypal when making a payment;

- custom - here service info, then we will need to identify the user;

- amount - payment amount;

- currency - payment currency. Possible options here .

- no_shipping = 1 - we indicate that the accession is not carried out.



Account setup





Further, to receive payments to your account, this same account must be properly configured.



Paypal supports two methods of transferring transaction data to our script: PDT (Payment Data Transfer) and IPN (Instant Payment Notification). As I understand it, the difference is that when using PDP from Paypal, one single message comes after the user makes a payment (that is, when money from the user is already on the way to your account). When using IPN, Paypal generates several messages, notifying us of each separate stage of the payment. To solve my problem, the PDT was quite enough, which I did.



The process for enabling PDT is described here . Down there is an Activating PDT section.



The essence of the PDT is at the end of the payment, Paypal sends the specified script GET-salary, in which it transfers the transaction number, its status, amount, etc. Paypal itself has a transaction authentication mechanism - we send a certain type POST request to their address with the received transaction number. In response, either an error code or a description of the transaction is received - the status, the amount, and a bunch of other official data.



Script Algorithm





Actually, what is required from the script:

1. get this data.

2. check the type of transfer - if you use regular payment (buy now). then the transaction type must be web_accept;

3. check the recipient's email and recipient's account id. (bussiness, receiver_email, receiver_id fields);

4. The custom field contains the service info received from us, for example

Id user - check it.

5. The txn_id field contains the transfer number in the paypal system. check

so that there are no repeat payments.

6. after that, if the payment_status = Complete field, i.e. payment

normally completed, then we carry out the payment already at home, with any other

status - some troubles.

The amount and currency will be in the mc_gross and mc_currency fields.

A complete list of all the parameters transmitted by Paypal using PDT (and even with IPN too) here .



Now about the buns that promised earlier. They belong to the custom field, which we ourselves send Paypal. You can, of course, simply write the user id there and not bathe, but we are not looking for easy ways. In this field, it is quite possible to record the id of the record with the description of the payment in our system, and already there the user is saved, remember the type of service to which the user has purchased, the amount, etc. This will allow, for example, to track purchases that have not been paid, as well as, when receiving data from Paypal, you can check with your saved, which gives a small + to security.



And finally, a bit of code



  1. < ? php
  2. // this function is used to get data about transfer from Paypal
  3. // the code of the function itself is taken from Paypal's site; there are examples in different languages ​​somewhere
  4. function get_paypal_data ( $ tx_token, $ auth_token ) {
  5. $ req = 'cmd = _notify-synch' ;
  6. $ req. = "& tx = $ tx_token & at = $ auth_token" ;
  7. // post back to paypal system to validate
  8. $ header. = "POST / cgi-bin / webscr HTTP / 1.0 \ r \ n " ;
  9. $ header. = "Content-Type: application / x-www-form-urlencoded \ r \ n " ;
  10. $ header. = "Content-Length:" . strlen ( $ req ) . " \ r \ n \ r \ n " ;
  11. $ fp = fsockopen ( 'www.paypal.com' , 80 , $ errno, $ errstr, 30 ) ;
  12. if ( ! $ fp ) {
  13. // HTTP ERROR
  14. return false ;
  15. } else {
  16. fputs ( $ fp, $ header. $ req ) ;
  17. // read the body data
  18. $ res = '' ;
  19. $ headerdone = false ;
  20. while ( ! feof ( $ fp ) ) {
  21. $ line = fgets ( $ fp, 1024 ) ;
  22. if ( strcmp ( $ line, " \ r \ n " ) == 0 ) {
  23. // read the header
  24. $ headerdone = true ;
  25. } elseif ( $ headerdone ) {
  26. // header has been read. now read the contents
  27. $ res. = $ line ;
  28. }
  29. }
  30. }
  31. return $ res ;
  32. }
  33. // from GET, we take only the ID of the transaction, everything else does not interest us, we will receive this data from Paypal in response to our request
  34. $ tx = @ $ _ GET [ 'tx' ] ;
  35. if ( ! $ tx ) {
  36. error_log ( '[paypal] ERROR: Tx are absent !!!' ) ;
  37. return false ;
  38. }
  39. // send a Paypal request to get transaction data
  40. // PAYPAL_IDENTITY_TOKEN - constant with the token obtained when the PDT is activated
  41. $ res = get_paypal_data ( $ tx, PAYPAL_IDENTITY_TOKEN ) ;
  42. $ history. = ( '[paypal] post request result for' . $ tx. " \ n " . $ res ) ;
  43. if ( ! $ res ) {
  44. $ history. = ( '[paypal] http error for' . $ tx ) ;
  45. exit ( ) ;
  46. }
  47. // parsim answer
  48. $ strs = explode ( " \ n " , $ res ) ;
  49. if ( $ strs [ 0 ] == 'FAIL' ) {
  50. // if the first line is FAIl, it means some sort of trampling
  51. // handle the error as required and exit
  52. exit ( ) ;
  53. } elseif ( $ strs [ 0 ] == 'SUCCESS' ) {
  54. // everything seems fine - parsim the rest of the parameters
  55. $ res_vars = array ( ) ;
  56. // parse paypal answer to array where key it's varname
  57. for ( $ i = 1 ; $ i < count ( $ strs ) ; $ i ++ ) {
  58. $ strs [ $ i ] = trim ( $ strs [ $ i ] ) ;
  59. if ( ! $ strs [ $ i ] ) continue ;
  60. $ vars = explode ( '=' , $ strs [ $ i ] ) ;
  61. if ( ! $ vars || count ( $ vars ) ! = 2 ) {
  62. // some trouble - go to the next parameter
  63. continue ;
  64. }
  65. $ res_vars [ $ vars [ 0 ] ] = $ vars [ 1 ] ;
  66. }
  67. // finally, in the res_vars array, we have all the transaction parameters
  68. // in the txn_type field - type of transaction. we are only interested in web_accept
  69. switch ( $ res_vars [ 'txn_type' ] ) {
  70. case 'web_accept' :
  71. // here we check all other fields: bussiness, receiver_id ...
  72. // if necessary, parse custom field
  73. // if everything is fine, then check the status of the payment
  74. switch ( @ $ res_vars [ 'payment_status' ] ) {
  75. case 'Completed' :
  76. // everything is fine - we send the goods to the user, charge the money to the virtual account, etc.
  77. break ;
  78. }
  79. break ;
  80. }
  81. }
  82. ? >

Source: https://habr.com/ru/post/82595/



All Articles