Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

PayPal API - iskustva

[es] :: PHP :: PayPal API - iskustva
(TOP topic, by boccio)
Strane: 1 2

[ Pregleda: 7299 | Odgovora: 24 ]

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.wxs.nl.



Profil

icon PayPal API - iskustva13.03.2006. u 10:38

Pozdrav,

Jel' radio ko vec sa ovim? PayPal nudi prijstojnu dokumentaciju, ali ako neko ima iskustva, neka se javi :)

Nemam jos konkretnih pitanja, instalirano je sve, ove nedelje cu pokusati da napravim interface ka PayPal sistemu, ali ako je neko vec radio, hteo bi, ako ste voljni da razmenimo iskustva...

Poz,
Sale

[Ovu poruku je menjao boccio dana 26.03.2006. u 01:08 GMT+1]
13.03.2006. u 10:38 

zrnoo
Vukašin
dizajn, programiranje
Beograd

Član broj: 73204
Poruke: 304
..AT.HighSpeedADSL.beotel.net.

ICQ: 56375637
Sajt: www.Tjuner.com


Profil

icon Re: PHP -> PayPal API - iskustva13.03.2006. u 22:57
nerazumem su uopste u to, ali evo neki link "ako ti ikad bude zatrebao" ! Mada verovatno neme velike slicnosti sa ovim (mislim jer nisam citao) :) , mada nikad se nezna :)))

http://www.zend.com/zend/tut/tutorial-paypal.php
13.03.2006. u 22:57 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PHP -> PayPal API - iskustva13.03.2006. u 23:18
Ola,

@zrnoo - sasvim drugaciji pristup na zend sajtu od onoga sto PayPal ima u tuotorijalu.

@JaHvram, ono sto sam do sada video / procitao / testirao:

Koriste Webservices, SOAP, sertifikate i naravno SSL.
Proces koji mene trenutno zanima jeste direktno placanje i nista drugo (postoje jos razne provere, povracaj novca, detalji transakcije, pretraga transakcije, masovno placanje, provera adrese itd itd itd).

Moj cilj je za sada da postignem sledece:
1. musterija na sajtu izabere proizvode;
2. klikne: plati putem paypal-a;
3. uloguje se u paypal;
4. vraca se na moj sajt i klikne: kupi
5. transfer se izvrsava na paypal-u
6. musterija dobija 'thank you' stranicu.

Konkretno, za mene su bitna 3 SOAP poziva:
1. SetExpressCheckout
2. GetExpressCheckoutDetails
3. DoExpressCheckoutPayment

Funkcionise po principu (ovo su samo podaci koje cu ja slati, ostali podaci me ne zanimaju):
1. musterija izabere zeljeni proizvod;
2. na PayPal dugme bira da plati putem PayPal-a;
3. Saljem prvi SOAP ka PayPal-u (sa cenom, bez shipping adres i sa 2 required polja: cancell i return url-om), a dobijam Token nazad, koji koristim da preusmerim musteriju ka PayPal-u;
4. PayPal prepoznaje musteriju po tokenu i daje log-in screen;
5. Musterija se uloguje i klikne na PayPal sajtu: Nazad na moj sajt (koriste return URL iz prvog SOAP poziva);
6. PayPal pozivom na return URL pokrece moj drugi SOAP poziv u kojem se nalazi samo token ka PayPal-u, a PayPal vraca payerID i payerInfo (ime, prezime i sl).
7. Na return URL-u prikazujem musteriji njegove podatke i dajem 2 mogucnosti: zavrsi kupovinu ili prekinu kupovinu. Ako izabere da prekine, tu se sve zavrsava. Ako izabere da zavrsi kupovinu onda:
8. Saljem treci SOAP poziv PayPal-u, sa tokenom i 'akcijom' = sale. PayPal izvrsava transakciju a meni vraca: TransactionID i PaymentInfo. Takodje, PayPal salje meni i korisniku mail sa obavestenjem o transakciji.
9. nakon success od PayPal-a, korisnik se prebacuje na 'thank you' stranu, u suprotnom mu se ispisuje greska koju je PayPal meni poslao.

Dakle, bitno je: token, koji se od samog pocetka pa do kraja provlaci. Takodje, u celom procesu su svega 6 varijabli obavezne:
1. ordertotal (suma novca);
2. maxamount (max suma novca, u mom slucaju isto kao i ordertotal);
3. returnurl
4. cancellurl
5. token
6. paymentaction > sale

Moram priznati da PayPal ima odlicnu dokumentaciju, izuzetno pregledno test okruzenje, kao i jednu alatkicu za pravljenje gotovih SOAP poziva!!! Ovo vrlo cenim, jer preko webinterface-a, mozes da sastavis SOAP poziv koji ti odgovara i bukvalno da ga kopiras. Uz minimalne izmene imas gotov code :)

Verujem da cu do vikenda zavrsiti i obaviti prvu kako test tako i pravu transakciju, pa cemo videti ;)

Sto se tice PayPal-a za podrucje bivde juge, SCG je pod Slovenijom :) Za Bih / Cro ne znam...

Poz,
Sale
13.03.2006. u 23:18 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.wxs.nl.



Profil

icon Re: PHP -> PayPal API - iskustva15.03.2006. u 12:11
Mali update. Samo kao naznaka, za sada sve radim na test platformi PayPal-a.

Napravio sam 3 SOAP poziva i sada uspesno mogu da odradim transakciju. nakon sto musterija izabere proizvod, prikazujem ih na stranici. Tu stoji PayPal dugme, koje poziva prvi SOAP call i salje:

- svotu novca koja treba da se prebaci;
- custom text (naziv proizvoda);
- return url;
- cancell url;

Musterija biva prebacena na paypal site, gde se loguje, a zatim vraca na return url koji sam zadao u SOAP-u.

Na toj stranici (return url) PayPal salje podatke o musteriji koja se ulogovala. Od podataka prikazujem musteriji:
- izabran proizvod;
- ukupnu cenu;
- mail i ime / prezime od musterije;

Takodje tu prikazujem sledece dugme, za potvrdu transakcije. Nakon provere od musterije, pritiskom na dugme, transakcija se obavlja, a musterija dobija podatke o transakciji kao i 'thank you' stranicu. Na ovoj stranici je i trigger da sve podatke zapisem u bazu i odradim jos nekoliko akcija...

Imao sam par problemcica oko array koju SOAP-a koji paypal vraca, ali sam se snasao. Vracaju super puno podataka, od kojih meni samo par treba :)

Sve u svemu, na test sistemu sam napravio da mogu ok transakcije da vrsim... Pred vikend cu prebaciti na live, pa cu da probam live :)

Poz,
Sale
15.03.2006. u 12:11 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PHP -> PayPal API - iskustva16.03.2006. u 10:08
Ok, jos jedan mali update.

Nakon sto se transakcija posalje PayPal-u (treci i poslednji SOAP poziv), vracam musteriji "thank you" stranicu + informacije o transakciji. Postoje 3 statusa koje transakcija moze da vrati:

- success;
- fail;
- pending.

Medjutim, PayPal ima jednu lepu funkcionalnost, takozvani IPN (Instant Payment Notification). Odnosno, treci SOAP poziv je samo nalog za izvrsenje transakcije. Ako je sve ok, ona se odradi u par sekundi nakon izdavanja ovog naloga. Medjutim, ukoliko musterija koristi echeck ili neku drugu vrstu placanja, za ciju transakciju je potrebno vise vremena, onda je IPN idealno resenje.

Naime, nakon treceg SOAP-a, jos nista ne radim povodom porudzbine koju je musterija narucila. Tek kada PayPal prebaci novac na moj PayPal nalog, IPN me obavestava automatski o tome, na unapred definisanu adresu. Ovo je automatizovan proces i komunikacije ide:

Ako imas SSL:
PayPal (IPN) -> tvoja adresa (php) sa podacima o transakciji uz SecretKey -> PHP na tvojoj stranici prihvata, uporedi sa transakcijom iz treceg SOAP poziva i ako je ok, odradjujes sta treba (saljes porudzbinu, saljes mail o potvrdi itd...);

Ako nemas SSL:
PayPal (IPN) -> tvoja adresa (php) -> PayPal SSL adresa (saljes _sve_ podatke koje su oni tebi poslali, provere radi) -> tvoj sajt (PayPal salje 'VERIFIED' ili 'FAILED'). Ako ti stigne verified, odradjujes sta treba (porudzbina, mail itd...);

Jos jednom, PayPal ovde odlicno izlazi u susret sa potrebnom dokumentacijom, primerima skripti za PHP (i ostale jezike), forumom i teh podrskom.
Od +/- 450 stranica dokumentacije kroz koju sam prosao, samo jedna stvar mi nije bila jasna (poslao mail teh podrsci danas).

Eto, to je mali update... Ocekujem i dalje da ce za vikend sve ici live :)

Poz,
Sale
16.03.2006. u 10:08 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
195.252.99.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PHP -> PayPal API - iskustva25.03.2006. u 19:33
Hmmm... daj malo koda, nemoj da si stipsa :D

Bilo bi lepo da se napravi klasa sa kojom bi moglo ovo da se odradi...
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
25.03.2006. u 19:33 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PHP -> PayPal API - iskustva25.03.2006. u 20:04
Cao,

Nije problem. Ceo proces sam odradio i automatizovao, stim sto mi je kod trenutno razbacan na nekoliko strana. Ali sutra cu da ga sumiram, pa cu postaviti...

@gost123: ciljna grupa mi je bilo ko, ne mora samo ex-juga ;)

Poz,
Sale
25.03.2006. u 20:04 

mVeliki
Miroslav Ćurčić
Novi Sad

Član broj: 19034
Poruke: 575
..mtsns-ns.customer.sbb.co.yu.



Profil

icon Re: PHP -> PayPal API - iskustva25.03.2006. u 20:50
Uradio sam pre par meseci jedan sajt sa PayPal placanjem i moram da priznam da je bilo vrlo jednostavno.

Nikakav SOAP nisam koristio, vec suv php, i to ona varijanta bez SSLa.
Jedino sto je IPNu trebalo po par minuta (nekad i 15-ak) da prosledi transakciju.

Imate sasvim upotrebljive primere na samom sajtu, a test-okruzenje se odlicno pokazalo.
"The quieter you become, the more you are able to hear."
25.03.2006. u 20:50 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PHP -> PayPal API - iskustva25.03.2006. u 21:55
PHP-om pozivas SOAP call... ;)

I kod mene je bez SSL-a, a live IPN jos ne znam, nisam jos live... :) Test je ok, ali ponekada spor (IPN stizao i sa 12 sati kasnjenja) :S

Poz,
Sale
25.03.2006. u 21:55 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PayPal API - iskustva29.03.2006. u 19:18
Ne stizem jos da ostavim code :( Nadam se za vikend... :)

Poz,
Sale
29.03.2006. u 19:18 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
195.252.99.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PayPal API - iskustva30.03.2006. u 16:46
Ajde... cekam(o) kod...
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
30.03.2006. u 16:46 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PayPal API - iskustva31.03.2006. u 21:13
Bice sutra popodne ;)

Poz,
Sale

i NE, nije prvoaprilska sala! :)
31.03.2006. u 21:13 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
195.252.99.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PayPal API - iskustva01.04.2006. u 21:27
E Smajli, nije da te pozurujem, al' ono, imas jos sat i po do kraja "sutrasnjeg popodneva"

Izgleda da jeste prvoaprilska shala
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
01.04.2006. u 21:27 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.speed.planet.nl.



Profil

icon Re: PayPal API - iskustva02.04.2006. u 19:55
eh... ne stizem, ne stizem :(

Elem, idemo.
Nekoliko napomena, varijable su izmenjene radi zastite ;)

Pocetak komunikacije sa PayPal-om.
order_confirm.php
Code:

$button = "
<form action='SetExpressCheckout.php' method='post'>
<input type = 'hidden' name = 'Price' value = '$totalprice'>
<input type = 'hidden' name = 'PriceMax' value = '$totalprice'>
<input type = 'hidden' name = 'SetOrderDescription' value = 'Package $pname ($paymentname)'>
<input type='image' src='https://www.paypal.com/en_US/i/btn/x-click-but03.gif' border='0' name='submit' alt='Make payments with PayPal - it's fast, free and secure!'>
<input type='hidden' name='encrypted' value='-----BEGIN PKCS7-----Bq0JFkacEHKlEeoNdXv8aRNXg5HoQZr9Gp9mLk1zkoaIUWnLU+==-----END PKCS7-----'>
</form>";


-----BEGIN PKCS7-----
i
-----END PKCS7-----

je napravio sam PayPal, a na osnovu public / private key, koji je smesten na mom i njihovom serveru (sama varijabla je _mnogo_ duza, pa lomi izlged ES-a, te sam je ja skratio). Dugme je takodje od PayPal-a, naravno namerno ga nisam menjao kako bi look & feel PayPal-a ostalo, posto su poznati, te samim tim znace nesto ;)

Kada korisnik klikne na pomenuto dugme, PayPal-u se salju parametri: Price, PriceMax, SetOrderDescription. Te parametre definise moj sajt, a na osnovu onoga sto je korisnik izabrao. Zatim korisnik stize na PayPal sajt, preko SetExpressCheckout.php, koji izgleda ovako:

SetExpressCheckout.php
(vidi kometare u kodu, za sta cemu sluzi! njih sam ja dodao)
Code:

<?php

session_start();

// ucitavanje paypal api-ja, ovo je 1-na-1 stavljeno na server, iz njihovog primera
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';

// ucitava public key i settings od mog PayPal racuna
// kod mene smesteni u /var/paypal
$handler =& ProfileHandler_File::getInstance(array (
  'path' => '/var/paypal',
  'charset' => 'iso-8859-1',
));

if (Services_PayPal::isError($handler)) {
    var_dump($handler->getMessage());
    exit;
}

// ovde PayPal provera moje podatke, saljuci moju identifikaciju PayPal serveru
$profile =& APIProfile::getInstance('dasda78sd8a7sd', $handler);

if (Services_PayPal::isError($profile)) {
    var_dump($profile->getMessage());
    exit;
}

// saljem sifru, da se identifikuje prethodni API poziv
$profile->setAPIPassword('GDGDSFR545GDGFG');

// ok, to sam ja, kaze PayPal
$caller =& Services_PayPal::getCallerServices($profile);

if (Services_PayPal::isError($caller)) {
    var_dump($caller->getMessage());
    exit;
}

// Koji servis API-ja koristim
$OrderTotal =& Services_PayPal::getType('BasicAmountType');

if (Services_PayPal::isError($OrderTotal)) {
    var_dump($OrderTotal);
    exit;
}

// Podesavam sta naplacujem i koliko
// $_POST['Price'] je iz order_confirm.php
$OrderTotal->setattr('currencyID', 'EUR');
$OrderTotal->setval($_POST['Price'], 'iso-8859-1');
$MaxAmount =& Services_PayPal::getType('BasicAmountType');

if (Services_PayPal::isError($MaxAmount)) {
    var_dump($MaxAmount);
    exit;
}

// Podesavamo drugi parametar - maximalnu cenu koju proizvod moze da dostigne
$MaxAmount->setattr('currencyID', 'EUR');
$MaxAmount->setval($_POST['PriceMax'], 'iso-8859-1');
$SetExpressCheckoutRequestDetails =& Services_PayPal::getType('SetExpressCheckoutRequestDetailsType');

if (Services_PayPal::isError($SetExpressCheckoutRequestDetails)) {
    var_dump($SetExpressCheckoutRequestDetails);
    exit;
}

// Podesavamo ostale parametre, kod mene konkretno:
// ne treba mi shipping adresa, max cenu, zatim:
// cancellurl - gde da se korisnik 'vrati' na moj sajt ako odustane od kupovine;
// returnurl - gde da se vrati ako potvrdi kupovinu
// ordertotal (ukupna cena, odnosno zbir svih proizvoda)
// poslednje je koja vrsta PayPal servisa je u pitanju (pored ovoga postoji jos recimo Shopping Cart).
$SetExpressCheckoutRequestDetails->setNoShipping('1', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setMaxAmount($MaxAmount);
$SetExpressCheckoutRequestDetails->setCancelURL('http://www.nekimojdomen.com/signup_cancell.php', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setReturnURL('http://www.nekimojdomen.com/signup_confirm.php', 'iso-8859-1');
$SetExpressCheckoutRequestDetails->setOrderTotal($OrderTotal);
$SetExpressCheckout =& Services_PayPal::getType('SetExpressCheckoutRequestType');

if (Services_PayPal::isError($SetExpressCheckout)) {
    var_dump($SetExpressCheckout);
    exit;
}

// Izvrsavanje API-a
$SetExpressCheckout->setSetExpressCheckoutRequestDetails($SetExpressCheckoutRequestDetails);

$result = $caller->SetExpressCheckout($SetExpressCheckout);

if (Services_PayPal::isError($result)) { 
    var_dump($result);
}
else
{
    // uspesno prosao SOAP call, onda se ide na PayPal sajt, sa tokenom, koji je gore kreiran i meni vracen
    // SOAP call succeded, let's move on...
    $url = "https://www.sandbox.paypal.com...d=_express-checkout&token=";
    $token = $result->getToken();
    $_SESSION['mycrontab_signup']['token'] = $token;
    header("Location: $url$token");   
}


?> 

U ovom gore kodu, se ukratko desava:
saljem podatke o kupovini PayPal serveru (i tom prilikom se identifikujem). Na ovaj nacin 'spremam' PayPal, da cu poslati musteriju. Ako sve prodje kako treba, PayPal uzvraca sa token-om, koji prosledjujem na kraju u URL-u. Sada, kada korisnik stigne na PayPal sajt, PayPal zna vec o kome se radi, te ispisuje korisniku sve relevantne informacije. Korisnik se ovom prilikom loguje na PayPal sa svojim nalogom. Ako klikne: continue, PayPal vraca korisnika na moj sajt (returnurl), a istovremeno PayPal salje meni informacije o korisniku koje koristim u sledecem fajlu:

signup_confirm.php
(komentar, ponovo u samom kodu)
Code:

<?php

require_once("class2.php");
require_once(HEADERF);

// let's see if they are coming from good page, no direct linking!
if($_SESSION['signup']['page'] != '1')
{
    ob_start();
    echo "You will be redirected to SignUp page in 10 seconds.<br>
    Or, you can click <a href = 'signup'>here</a> to go there immediately.";
    sleep(10);
    header("Location: http://www.nekimojdomen.com/signup.php");
    require_once(FOOTERF);
    ob_end_clean();
}

// PayPal API, 1-na-1 kopirano sa PayPal sajta
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';

session_start();

// Provera ko sam ja (key i ispod password)
$handler =& ProfileHandler_File::getInstance(array (
  'path' => '/var/paypal',
  'charset' => 'iso-8859-1',
));

if (Services_PayPal::isError($handler)) {
    var_dump($handler->getMessage());
    exit;
}

$profile =& APIProfile::getInstance('sdfr43rfwetrf534e', $handler);

if (Services_PayPal::isError($profile)) {
    var_dump($profile->getMessage());
    exit;
}

$profile->setAPIPassword('SDFRT453FDE34');

$caller =& Services_PayPal::getCallerServices($profile);

if (Services_PayPal::isError($caller)) {
    var_dump($caller->getMessage());
    exit;
}

$GetExpressCheckoutDetails =& Services_PayPal::getType('GetExpressCheckoutDetailsRequestType');

if (Services_PayPal::isError($GetExpressCheckoutDetails)) {
    var_dump($GetExpressCheckoutDetails);
    exit;
}

// uzimamo token, to nam je identifikacije ove transakcije
$GetExpressCheckoutDetails->setToken($_SESSION['signup']['token'], 'iso-8859-1');

$result = $caller->GetExpressCheckoutDetails($GetExpressCheckoutDetails);

if (Services_PayPal::isError($result)) { 
    var_dump($result);
}
else
{
    /* Success */
    //var_dump($result);
    
    // storing all neccessary parameters
    // data needed for the payment proccess
    // Ovde saznajemo ko nam je korisnik, kako bi korisnik proverio svoje podatke, pre definitivne kupovine!!
    $fname = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->getFirstName();
    $lname = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->getLastName();
    $token = $result->GetExpressCheckoutDetailsResponseDetails->getToken();
    $custmail = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->getPayer();
    $custid = $result->GetExpressCheckoutDetailsResponseDetails->PayerInfo->getPayerID();
    
    // data needed for DB
    $purchase_time = $result->getTimestamp();
    $ack = $result->getAck();
    $_SESSION['signup']['first_name'] = $fname;
    $_SESSION['signup']['last_name'] = $lname;
    $_SESSION['signup']['payer_email'] = $custmail;
    $_SESSION['signup']['payer_id'] = $custid;
    
    // Let's show the user details of the transaction
    
    $transtable = "
    <form name = 'doexpresschechout' action = 'signup_complete.php' method = 'POST'>
    <table width = 80% border = 0>
    <tr>
        <td colspan = 2><center><b>Order confirmation</b></center></td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
        <td colspan = 2><center><b>Your details</b></center></td>
    </tr>
    <tr>
        <td>First name</td>
        <td>$fname</td>
    </tr>
    <tr>
        <td>Last name</td>
        <td>$lname</td>
    </tr>
    <tr>
        <td>E-Mail</td>
        <td>$custmail</td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
        <td colspan = 2><center><b>Product info</b></center></td>
    </tr>
    <tr>
        <td>Product</td>
        <td>".$_SESSION['signup']['product']."</td>
    </tr>
    <tr>
        <td>Contract period</td>
        <td>".$_SESSION['signup']['contract']."</td>
    </tr>
    <tr>
        <td>Payment</td>
        <td>".$_SESSION['signup']['payment']."</td>
    </tr>
    <tr>
        <td>Price</td>
        <td>".$_SESSION['signup']['price']."</td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
        <td colspan = 2><center><input type='image' src='e107_images/x-click-but01.gif' border='0' name='submit' alt='Make payments with PayPal - it's fast, free and secure!'></center></td>
    </tr>
    <tr>
        <td>
        <input type = 'hidden' name = 'token' value = '".$_SESSION['signup']['token']."'>
        <input type = 'hidden' name = 'payerid' value = '".$custid."'>
        <input type = 'hidden' name = 'paymentdetails' value = '".$pdetails."'>
        <input type = 'hidden' name = 'ordertotal' value = '".$_SESSION['signup']['price']."'>
    </table>
    </form>";
    
    // u tabeli imamo 4 hidden polja, koja saljemo na sledecu stranicu jer su potrebna za izvrsenje transakcije
    echo $transtable;
}

require_once(FOOTERF);

?>


u ovom fajlu smo primili korisnika nazad od PayPal-a. Sada je korisnik ulogovan u svoj PayPal nalog, te znamo ko je. Nakon sto korisniku jos jednom prikazemo sve podatke o kupovini, nudimo mu opciju da pritiskom na dugme izvrsi transakciju. To se desava u fajlu signup_confirm.php. Zanimljivo je samo to da PayPal salje nekoliko podataka o samom korisniku. Mene je zanimalo samo ovo gore navedeno, ali izmedju ostalog moguce je recimo saznati odakle je korisnik, ima li 'overen' PayPal nalog ili ne itd...

signup_confirm.php
(opet, komentari u samom fajlu)
Code:

<?php

session_start();

// PayPal API
require_once 'Services/PayPal.php';
require_once 'Services/PayPal/Profile/Handler/File.php';
require_once 'Services/PayPal/Profile/API.php';

require_once("class2.php");
require_once(HEADERF);

// let's see if they are coming from good page, no direct linking!
if($_SESSION['signup']['page'] != '1')
{
    echo "You will be redirected to SignUp page in 10 seconds.<br>
    Or, you can click <a href = 'signup'>here</a> to go there immediately.";
    wait(10);
    header("Location: http://www.nekimojdomen.com/signup.php");
    require_once(FOOTERF);
}

// provera ko sam ja kod PayPal-a (public / private key)
$handler =& ProfileHandler_File::getInstance(array (
  'path' => '/var/paypal',
  'charset' => 'iso-8859-1',
));

if (Services_PayPal::isError($handler)) {
    var_dump($handler->getMessage());
    exit;
}

$profile =& APIProfile::getInstance('c8d566788388ad83feda294b69da245a', $handler);

if (Services_PayPal::isError($profile)) {
    var_dump($profile->getMessage());
    exit;
}

// saljem sifru za moj key
$profile->setAPIPassword('FDMEC9SXW6R7ZXM4');

// PayPal provera ko sam ja
$caller =& Services_PayPal::getCallerServices($profile);

if (Services_PayPal::isError($caller)) {
    var_dump($caller->getMessage());
    exit;
}

$OrderTotal =& Services_PayPal::getType('BasicAmountType');

if (Services_PayPal::isError($OrderTotal)) {
    var_dump($OrderTotal);
    exit;
}

// Podesavamo sta treba transakcija da sadrzi
$OrderTotal->setattr('currencyID', 'EUR');
$OrderTotal->setval($_SESSION['signup']['price'], 'iso-8859-1');
$PaymentDetails =& Services_PayPal::getType('PaymentDetailsType');

if (Services_PayPal::isError($PaymentDetails)) {
    var_dump($PaymentDetails);
    exit;
}

// Saljemo sve potrebne podatke PayPal-u, koji ce se izmedju ostalog pojaviti korisniku u transakciji
$PaymentDetails->setOrderDescription($_SESSION['signup']['product'] ($_SESSION['signup']['contract']), 'iso-8859-1');
$PaymentDetails->setCustom('Nekimojdomen.com first purchase', 'iso-8859-1');
$PaymentDetails->setOrderTotal($OrderTotal);
$DoExpressCheckoutPaymentRequestDetails =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestDetailsType');

if (Services_PayPal::isError($DoExpressCheckoutPaymentRequestDetails)) {
    var_dump($DoExpressCheckoutPaymentRequestDetails);
    exit;
}

// DoExpressCheckoutPaymentRequestDetails --> ovo govori PayPal-u: izvrsi transakciju
// navedeni parametri su obavezni, a ima jos gomila opcionih koji se mogu slati
$DoExpressCheckoutPaymentRequestDetails->setPaymentDetails($PaymentDetails);
$DoExpressCheckoutPaymentRequestDetails->setPayerID($_POST['payerid'], 'iso-8859-1');
$DoExpressCheckoutPaymentRequestDetails->setToken($_POST['token'], 'iso-8859-1');
$DoExpressCheckoutPaymentRequestDetails->setPaymentAction('Sale', 'iso-8859-1');
$DoExpressCheckoutPayment =& Services_PayPal::getType('DoExpressCheckoutPaymentRequestType');

if (Services_PayPal::isError($DoExpressCheckoutPayment)) {
    var_dump($DoExpressCheckoutPayment);
    exit;
}

$DoExpressCheckoutPayment->setDoExpressCheckoutPaymentRequestDetails($DoExpressCheckoutPaymentRequestDetails);

// izvrsavanje transakcije
$result = $caller->DoExpressCheckoutPayment($DoExpressCheckoutPayment);

if (Services_PayPal::isError($result)) { 
    var_dump($result);
}
else
{
    // debug version
    
    //echo "<pre>"; print_r($result); echo "</pre>";
    //echo "<pre>"; print_r($_SESSION); echo "</pre>";
    
    // transaction has been made; Let's collect all data and present it to the customer.

    // sakupljamo podatke potrebne kako za mene samog (za bazu i ostalo), tako i za korsnika, da potvrdimo transakciju
    $ack = $result->getAck();
    $transid = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getTransactionID();
    $transtype = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getTransactionType();
    $paymenttype = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentType();
    $paymentdate = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentDate();
    $status = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPaymentStatus();
    $reason = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->getPendingReason();
    
    // check if we got error!
    // Ovde slede nekoliko mogucih gresaka i odgovarajuca poruka uz iste
    if($ack == "Failure")
    {
        // collect error number from PayPal and match it in database
        $errornr = $result->Errors->getErrorCode();
        $sql = new db();
        $sql->db_Select("paypal_error_codes","*","WHERE errorcode = $errornr",'');
        $geterror = $sql->db_Fetch();
        
        // present it in nice table
        $error_table = "
        <table>
        <tr>
            <td><center><b>Error!</b></center></td>
        </tr>
        <tr>
            <td>".nl2br($geterror['comment'])."</td>
        </tr>
        <tr>
            <td><a href = 'signup.php'>Sign up again</a></td>
        </tr>
        </table>";
        
        echo $error_table;
        
        require_once(FOOTERF);
        exit;
    }
        
    // check status;
    // possible values: completed or pending
    if($status == "Completed")
    {
        $status_message = "Your purchase has been successfuly received by PayPal.";
    }
    if($status == "Pending")
    {
        // all standard pending message
        $status_message = "Your purchase has been sent to PayPal. However, it could not been proccessed immediately
        and is now in pending status.<br>";
        // scope through pending status and prepare matching information for customer
        switch ($_POST['reason'])
        {
            case "none":
               $status_message .= "PayPal did not send any additional information about the pending reason.<br>
               As soon as purchase has been proccessed you shall be informed by PayPal and by Nekimojdomen at your email address.";
               break;
            case "echeck":
               $status_message .= "Your payment has been made through eCheck. PayPal needs some time to clear this transactio.
               As soon as this has been done, you will receive information by e-mail from Nekimojdomen with your username and password.";
               break;
            case "other":
               $status_message .= "PayPal did not provide any pending reason. If you belive that transaction should be
               immediate, you can contact PayPal customer services to clarify pending status. When and if transaction gets proccessed
               by PayPal, you shall be immediately notifed.";
               break;
           }
    }
    
    // start creating nice output for the customer
    $order_confirmed = "
    <table>
    <tr>
        <td colspan = 2><center><b>Puchase completed</b></center></td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
        <td colspan = 2>This is the confirmation of your purchase</td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
           <td>Status</td>
           <td>$status</td>
       </tr>
       <tr>
           <td colspan = 2>$status_message</td>
       </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
       <tr>
           <td>Ordering date</td>
           <td>$paymentdate</td>
       </tr>
       <tr>
           <td>Charged ammount</td>
           <td>".$_SESSION['signup']['price']."</td>
       </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
        <td colspan = 2>You will be receiving shortly your log in information per e-mail</td>
    </tr>
    <tr>
        <td colspan = 2><br></td>
    </tr>
    <tr>
        <td colspan = 2><center><i>Thank you for puchasing Nekimojdomen product!</i></center></td>
    </tr>
       </table>";

    
    echo $order_confirmed;
    
    // let's store some data into database, so that we can match when payment has been received
    $sql2 = new db();
    $preorder = $sql2->db_Insert("paypal_orders","'$transid','$transtype','".$_SESSION['signup']['first_name']."','".$_SESSION['signup']['last_name']."','".$_SESSION['signup']['payer_email']."','".$_SESSION['signup']['payer_id']."','aleksandar@skodric.com','".$_SESSION['signup']['product']."','$paymentdate','','1'");

    mail("askodric@gmail.com","Nekimojdomen.com -- order confirmation","You just order something... thanx :)");
    //echo "<br><br>".$_SESSION['signup']['first_name']."','".$_SESSION['signup']['last_name']."','".$_SESSION['signup']['payer_email']."','".$_SESSION['signup']['payer_id']."','$paypalmail','".$_SESSION['signup']['package']."','".$_SESSION['signup']['payer_id']."','$paymentdate','','1'";
}

session_destroy();

require_once(FOOTERF);

?>

Ovo je poslednje sto korisnik vidi. Ovde mu se prikazuje poruka koju PayPal salje meni, a ja istu (uz manje izmene, jezicke) pruzam korisniku.
Ukoliko je transakcija ok prosla, poslednji korak jeste da PayPal to potvrdi, a to se odradjuje preko IPN (Instant Payment Notification). Naime, PayPal poziva unapred definisani url (koji stoji u mom PayPal nalogu).

autoprocesspayment.php
(komentari u kodu)
Code:

<?php

require_once("../class2.php");

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value)
{
    $value = urlencode(stripslashes($value));
    $req .= "&$key=$value";
}

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$txn_type = $_POST['txn_type'];
$custom = $_POST['custom'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$payer_first_name = $_POST['first_name'];
$payer_last_name = $_POST['last_name'];

if (!$fp)
{
    // HTTP error occured, we shall not log this one, but rather send e-mail. If neccessary, manual log can be done later
    $subject = "IPN Failed: connection to paypal not established";
    $body = "$txn_id; $txn_type; $custom; $receiver_email; $payer_email; $payment_status; $payment_amount.";
    mail("payment@skodric.com", $subject, $body);
    
    // let's update status of transaction
    $sql = new db();
    $put = $sql->db_Update("paypal_orders","status = 6  where txn_id = $txn_id");
    exit;
}
else
{
    // let's log all data first, preparing nicely layout to store files
    $date = date("Y-m-d");
    $data = "
    Received on: $date<br><br>
    
    Transaction ID: $txn_id ($txn_type)<br>
    Item purchased: $item_name<br>
    Payment status: $payment_status<br>
    Payment ammount: $payment_amount $payment_currency<br>
    Custom message: $custom<br><br>
    
    Receiver e-mail: $receiver_email<br>
    Payer e-mail: $payer_email";
    // obozavam logging, te _SVE_ logujem :)
        $handle = fopen("/path/to/log/ipn-all.$txn_id","w+");
    fwrite($handle, $data);        

    fputs ($fp, $header . $req);
    while (!feof($fp))
    {
        $res = fgets ($fp, 1024);
        if (strcmp ($res, "VERIFIED") == 0)
        {
            // get data from database, as we will need it
            // comparison is Transaction id, so if does not exist, something is wrong!
            $sql = new db();
            $gettrans = $sql->db_Count("paypal_orders","(txn_id)","where txn_id = '$txn_id'");
            
            if($gettrans <= 0)
            {
                // no records found in DB! something is not OK!
                echo "no records";
                exit;
                
            }
            
            // check that receiver_email is your Primary PayPal email
            if($receiver_email != "aleksandar@skodric.com")
            {
                echo "receiver mail is not correct";
                exit;
            }
            
            // Status is OK, let's make things
            if($payment_status == "Completed")
            {
                do your stuff here, like create accounts, start billing etc...
                                exit;
            }
            if($payment_status == "Denied")
            {
                echo "payment denied, see paypal 4 more info";
                exit;
            }
            if($payment_status == "Expired")
            {
                echo "transactin expired, try again";
                exit;
            }
        }    
        else if (strcmp ($res, "INVALID") == 0)
        {
            // log for manual investigation
                        make some logs here
            echo "payment proccess call went wrong...";
            exit;
        }
    }
    fclose ($fp);
}
?>


Ovaj poslednji fajl hvata sta PayPal kaze o transakciji. Naime, prethodni fajl je poslao zahtev PayPal-u da odradi transakciju, a ovaj sakuplja podatke o transakciji.

Elem, sve ovo gore je sa mog pre-production servera, te nemojte obracati paznju na komentare i slicno :) Ako ima pitanja - tu sam ;)

Poz,
Sale
02.04.2006. u 19:55 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
195.252.99.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PayPal API - iskustva03.04.2006. u 02:35
U drugom bloku koda, pri kraju dole imas:

Code:
$url = "https://www.sandbox.paypal.com...d=_express-checkout&token=";


Mislim da ti se malo skratio link Da li i mi dobijamo negde ove linkve ili ces morati da ispravljas postove?

Sad jos da dodjem do PayPal naloga pa da probam, hehe... hvala na kodu

[Ovu poruku je menjao JaHvram dana 03.04.2006. u 03:36 GMT+1]
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
03.04.2006. u 02:35 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.wxs.nl.



Profil

icon Re: PayPal API - iskustva03.04.2006. u 13:43
Da video sam, ES ga skratio :S
Inace, taj kod je standardan za PayPal test server i stoji kako u primerima koji oni daju, tako i u dokumentaciji...

Ako ima potrebe, pokusacu veceras opet da stavim :)

Poz,
Sale
03.04.2006. u 13:43 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
195.252.99.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PayPal API - iskustva03.04.2006. u 15:51
Ajde zipuj (raruj, targuzuj, stagod ti odgovara ) pa okaci uz poruku, tako nista nece biti messed up!
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
03.04.2006. u 15:51 

frroggy
Novi Sad

Član broj: 26282
Poruke: 85
..mtsns-ns.customer.sbb.co.yu.

Sajt: www.gssys.net


Profil

icon Re: PayPal API - iskustva29.06.2006. u 10:40
Pozdrav,

zasto nastade tajac sve ovo vreme. Sta se dalje desavalo? Jel sve radi kako treba? Iskustva? Bili bi smo zahvalni da cujemo izvestaj nakon evo vec dva meseca.


Citat:
Sto se tice PayPal-a za podrucje bivde juge, SCG je pod Slovenijom :) Za Bih / Cro ne znam...


Da li ovo znaci, da ako hocu da otvorim account moram izabrati Sloveniju kao moju zemlju?
29.06.2006. u 10:40 

SmilieBG
Aleksandar Skodric
NL

Moderator
Član broj: 13094
Poruke: 1744
*.adsl.wanadoo.nl.



Profil

icon Re: PayPal API - iskustva15.02.2007. u 23:16
Eh, zena, deca, kuca, posao... Nemam nista od toga, pa opet nemam vremena, sta li ce tek biti kad budem imao sve to :)

Salu na stranu.

Kod sam naravno zavrsio jos onda i funkcionise. Medjutim, sajt za koji sam ga radio nije vise u funkciji, pa moram da prekopam po hardu malo.

Inace, nikada nisam imao problema sa PayPal-om, zaista sjajno radi. Tech support im je malo spor, ali boze moj.

Postavicu zipovan kod za vikend.

Poz,
Sale

ps. naravno, ako imate specificna pitanja, pitajte :)
15.02.2007. u 23:16 

Nemanja Avramović
PHP developer, Webinsane
Mladenovac, Srbija

Moderator
Član broj: 32202
Poruke: 3769
194.106.174.*

ICQ: 266136396
Sajt: www.avramovic.info


Profil

icon Re: PayPal API - iskustva15.02.2007. u 23:27
Hvala što si se javio SmilieBG, očekujemo konkretan kod.
Ja sam za potrebe jednog svog sajta kupio PayDownloadPal, mada je to stara skripta, ali sam je uz neke izmene uspešno poterao kod sebe na serveru.
Ipak, to mi nije dosta, bolje je kad imam konkretan, (relativno) kratak i jasan PHP kod koji mogu da koristim svuda i za sve potrebe.

Ne znam da li ste znali, ali i MoneyBookers (koji za razliku od Paypal-a radi i sa nama) ima IPN (Instant Payment Notification), mada su ga vrlo dobro sakrili ... ali mislim da je to za neku drugu temu
Moj sajt. Moj blog. Moj avatar. Moj grad. Moja frizura.

[NE PRUŽAM PODRŠKU ZA