mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 06:06:00 -06:00
Bazaar/IPNServer : an SCGI-based server for PayPal Instant Payement Notification
git-svn-id: svn://ultimatepp.org/upp/trunk@4584 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
0fe3512197
commit
ef2d7d8bf2
4 changed files with 148 additions and 0 deletions
88
bazaar/IPNServer/IPNServer.cpp
Normal file
88
bazaar/IPNServer/IPNServer.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include "IPNServer.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
// constructor - defaults to port 8787 and connection timeout of 5 minutes (300 sec.)
|
||||
IPNServer::IPNServer(int port) : ScgiServer(port)
|
||||
{
|
||||
}
|
||||
|
||||
void IPNServer::OnAccepted()
|
||||
{
|
||||
Cout() << "Accepted connection from client " << FormatIP(clientIP) << "\n";
|
||||
}
|
||||
|
||||
void IPNServer::OnRequest()
|
||||
{
|
||||
// we handle just POST requests, GET not allowed
|
||||
if(HasPostData())
|
||||
{
|
||||
// create context for ssl connection
|
||||
SSLContext context;
|
||||
if(!context.Create(const_cast<SSL_METHOD *>(SSLv3_client_method())))
|
||||
{
|
||||
Cerr() << "Error creating SSL context.";
|
||||
return;
|
||||
}
|
||||
|
||||
// re-send back data to paypal site, in order to check
|
||||
// if data was from them
|
||||
Socket answerSocket;
|
||||
if(!SSLClientSocket(answerSocket, context, payServer, payPort))
|
||||
{
|
||||
Cout() << "Error creating connection to PayPal\n";
|
||||
return;
|
||||
}
|
||||
String req = "cmd=_notify-validate";
|
||||
for(int i = 0; i < post.GetCount(); i++)
|
||||
req << "&" << ToLower(post.GetKey(i)) << "=" << UrlEncode(post[i]);
|
||||
|
||||
String header;
|
||||
header <<
|
||||
"POST /cgi-bin/webscr HTTP/1.0\r\n"
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
"Content-Length: " << req.GetCount() << "\r\n\r\n"
|
||||
;
|
||||
answerSocket.Write(header + req);
|
||||
|
||||
// wait for PayPal server answer
|
||||
req = "";
|
||||
while(answerSocket.IsOpen() && !answerSocket.IsEof() && !answerSocket.IsError())
|
||||
req << answerSocket.Read();
|
||||
answerSocket.Close();
|
||||
|
||||
// 'VERIFIED' or 'INVALID' answer are on last line of received HTTP packet;
|
||||
// the rest is just HTTP headers and can be discarded
|
||||
// in detail, the LAST part of req string must be "VERIFIED"
|
||||
if(req.Right(8) == "VERIFIED")
|
||||
{
|
||||
VectorMap<String, String> data;
|
||||
for(int i = 0; i < post.GetCount(); i++)
|
||||
data.Add(post.GetKey(i), post[i]);
|
||||
onVerified(data);
|
||||
}
|
||||
else
|
||||
onInvalid();
|
||||
}
|
||||
else
|
||||
Cout() << "No POST data on PayPal request\n";
|
||||
|
||||
// this one avoids "500 server error".... don't know why
|
||||
// but paypal do check the http response along with reply packet
|
||||
// on direct http access it'll show just a blank page
|
||||
clientSock.Write("Content-Type: text/plain\r\n\r\n");
|
||||
}
|
||||
|
||||
void IPNServer::OnClosed()
|
||||
{
|
||||
Cout() << "Connection with " << FormatIP(clientIP) << " closed\n";
|
||||
}
|
||||
|
||||
// runs the server
|
||||
void IPNServer::Run(void)
|
||||
{
|
||||
// runs the SCGI server
|
||||
ScgiServer::Run();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
45
bazaar/IPNServer/IPNServer.h
Normal file
45
bazaar/IPNServer/IPNServer.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _IPNServer_IPNServer_h_
|
||||
#define _IPNServer_IPNServer_h_
|
||||
|
||||
#include <Web/SSL/SSL.h>
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
class IPNServer : public ScgiServer
|
||||
{
|
||||
private:
|
||||
|
||||
void OnAccepted();
|
||||
void OnRequest();
|
||||
void OnClosed();
|
||||
|
||||
String payServer;
|
||||
int payPort;
|
||||
|
||||
// 'VERIFIED' answer handler
|
||||
Callback1<VectorMap<String, String> >onVerified;
|
||||
|
||||
// 'INVALID' answer handler
|
||||
Callback onInvalid;
|
||||
|
||||
public:
|
||||
|
||||
// constructor - defaults to port 8787
|
||||
IPNServer(int port = 8787);
|
||||
|
||||
// setup server and port for back confirmation message
|
||||
IPNServer &SetPayServer(String const &s) { payServer = s; return *this; }
|
||||
IPNServer &SetPayPort(int p) { payPort = p; return *this; }
|
||||
|
||||
// setting of handler
|
||||
IPNServer &SetVerifiedHandler(Callback1<VectorMap<String, String> >handler) { onVerified = handler; return *this; }
|
||||
IPNServer &SetInvalidHandler(Callback handler) { onInvalid = handler; return *this; }
|
||||
|
||||
// runs the server
|
||||
void Run(void);
|
||||
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
10
bazaar/IPNServer/IPNServer.upp
Normal file
10
bazaar/IPNServer/IPNServer.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
description "Instant Payement Notification server for PayPal\377";
|
||||
|
||||
uses
|
||||
Core,
|
||||
Web/SSL;
|
||||
|
||||
file
|
||||
IPNServer.h,
|
||||
IPNServer.cpp;
|
||||
|
||||
5
bazaar/IPNServer/init
Normal file
5
bazaar/IPNServer/init
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _IPNServer_icpp_init_stub
|
||||
#define _IPNServer_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#include "Web/SSL/init"
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue