line
stmt
bran
cond
sub
pod
time
code
1
package Business::PayPal;
2
3
1
1
69270
use 5.6.1;
1
4
4
1
1
6
use strict;
1
3
1
22
5
1
1
5
use warnings;
1
2
1
45
6
7
our $VERSION = '0.20';
8
9
1
1
665
use Net::SSLeay 1.14;
1
14171
1
57
10
1
1
9
use Digest::MD5 qw(md5_hex);
1
2
1
1341
11
12
our $Cert;
13
our $Certcontent;
14
15
my @certificates;
16
# added to 0.12 on 2014.04.19
17
push @certificates, <<'CERT';
18
-----BEGIN CERTIFICATE-----
19
MIIGCDCCBPCgAwIBAgIQCDTkU9Q6aFcjr/uxM85FfDANBgkqhkiG9w0BAQUFADCB
20
ujELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
21
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
22
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMr
23
VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTAeFw0x
24
NDA0MTUwMDAwMDBaFw0xNTA0MDIyMzU5NTlaMIIBCTETMBEGCysGAQQBgjc8AgED
25
EwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0
26
ZSBPcmdhbml6YXRpb24xEDAOBgNVBAUTBzMwMTQyNjcxCzAJBgNVBAYTAlVTMRMw
27
EQYDVQQRFAo5NTEzMS0yMDIxMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQH
28
FAhTYW4gSm9zZTEWMBQGA1UECRQNMjIxMSBOIDFzdCBTdDEVMBMGA1UEChQMUGF5
29
UGFsLCBJbmMuMRQwEgYDVQQLFAtDRE4gU3VwcG9ydDEXMBUGA1UEAxQOd3d3LnBh
30
eXBhbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+rkZNmW5t
31
bDVLiDI4u9zQCZXQmuQ2558KsPLX0jBiAx+txvRtEIT3eRu8dMCo44L+1AqTLj1L
32
EiStrV9d7RzJHG8Te+LBJU5GX087LlrLwVq0gs+to2XohjO17R14mafH1foQLvsR
33
TiNYBpaHcXVRc4wP9Mp8j5EleRPcsPDeCAcBC2TMV2oShmIXPl25Yj1Yeypu9qYw
34
QQL87GRyM9XVP2ttl/PBYb84O6tBR9TCA9c7WVed4aEq1njog1093apdF/2U1uV6
35
7wJjxqPGLVszCIv1pQO0/vIdq79enrh4OSAraGFP5JnyqsJNS0jLaMIQP/qausVq
36
U48i89fJ7aTVAgMBAAGjggG2MIIBsjBnBgNVHREEYDBegg53d3cucGF5cGFsLmNv
37
bYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5jb22CDGMucGF5cGFsLmNv
38
bYIOdG1zLnBheXBhbC5jb22CDHRtcy5lYmF5LmNvbTAJBgNVHRMEAjAAMA4GA1Ud
39
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwZgYDVR0g
40
BF8wXTBbBgtghkgBhvhFAQcXBjBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Quc3lt
41
Y2IuY29tL2NwczAlBggrBgEFBQcCAjAZGhdodHRwczovL2Quc3ltY2IuY29tL3Jw
42
YTAfBgNVHSMEGDAWgBT8ilC6nrklWntVhU+VAGOP6VhrQzArBgNVHR8EJDAiMCCg
43
HqAchhpodHRwOi8vc2Euc3ltY2IuY29tL3NhLmNybDBXBggrBgEFBQcBAQRLMEkw
44
HwYIKwYBBQUHMAGGE2h0dHA6Ly9zYS5zeW1jZC5jb20wJgYIKwYBBQUHMAKGGmh0
45
dHA6Ly9zYS5zeW1jYi5jb20vc2EuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQB2CKtk
46
9vQL5IG9WbI+pPz1A3UEWWq1/hI0KgScic3L4TxsIDnU6m8nNH9iHEVyETnARaoq
47
NVy2BuMIp48Ir4CyEM6lKFscSVUR62sqgMEJ7YJySMoZi+U0lDxQJndrGmO6b2PR
48
WO0rHbenbgQlmcOUA5DsD0yTgzWG43CEDTzOr06AStORP1UzLx9nhy8JokHAEEos
49
xIigb5Ms7zjSYcfs8zd9yTKlXB5IDoVsRyp/xjBewvYu3eNNrP/vSCbHUXRHMkYL
50
zXoKXVvFje0XvN4JvOmTqXyFnIimg7zW5R8FEN+yT6LFlwCLV8cN58dXV4d9E59c
51
XPfzzQCJDYWaonDa
52
-----END CERTIFICATE-----
53
CERT
54
55
# added to 0.14 on 2015.04.01
56
push @certificates, <<'CERT';
57
-----BEGIN CERTIFICATE-----
58
MIIGvjCCBaagAwIBAgIQWK6vRldyZAffQNciCpwKZzANBgkqhkiG9w0BAQUFADB3
59
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
60
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
61
IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTUwMzEyMDAwMDAwWhcNMTUxMDMx
62
MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
63
AhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
64
VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEERQKOTUxMzEtMjAyMTET
65
MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFjAUBgNVBAkU
66
DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoUDFBheVBhbCwgSW5jLjEUMBIGA1UECxQL
67
Q0ROIFN1cHBvcnQxFzAVBgNVBAMUDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
68
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqko1WvJvFcFF1v4GUgNuMBHrNVqFClp72D76
69
Waua/+BGR1RVPT09jHXoV36FQcdRo1+c1fZmR5T+LCK28gY9UxsKPYm3M6eD9dHS
70
SzbbqEwQHmSNUSyAzq24f6lNAyFd+/+dSVbv6Ufc87WFIlN9GrXkDTDh7DI+aihS
71
UVZeaiPk+imBgFlwbuFYsEhrtBDNMcxUzC+5+T5w5YXF9S2WEkxQqhygZ+5IJl7h
72
g0tuoM8GE9+7rKckYor30ha4m40RCp7jDQhSnEsejGznblDNUBoOo0XaINI+5LHG
73
fZonCVvo5XaerZHiABl+eABYXMN2i2xRVQ2RG++hZvxZF+ZESQIDAQABo4ICsDCC
74
AqwwWAYDVR0RBFEwT4IMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghJoaXN0
75
b3J5LnBheXBhbC5jb22CDHQucGF5cGFsLmNvbYIOd3d3LnBheXBhbC5jb20wCQYD
76
VR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
77
AQUFBwMCMGYGA1UdIARfMF0wWwYLYIZIAYb4RQEHFwYwTDAjBggrBgEFBQcCARYX
78
aHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGRoXaHR0cHM6Ly9k
79
LnN5bWNiLmNvbS9ycGEwHwYDVR0jBBgwFoAUS/ot5O4zMuLfDQGhhtOgOzq5rK4w
80
KwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3N0LnN5bWNiLmNvbS9zdC5jcmwwVwYI
81
KwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vc3Quc3ltY2QuY29tMCYG
82
CCsGAQUFBzAChhpodHRwOi8vc3Quc3ltY2IuY29tL3N0LmNydDCCAQUGCisGAQQB
83
1nkCBAIEgfYEgfMA8QB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQ
84
AAABTBAIx7wAAAQDAEcwRQIgUYscJgszMFrBx1zbtdYs7DsNnDyeiq570NWMnm0/
85
2R0CIQCe+byVBqzuGe1SvVzZg2sDM/juENHN6afDVITPPlOwfgB3AFYUBpov18Ls
86
0/XhvUSyPsdGdrm8mRFcwO+UmFXWidDdAAABTBAIyawAAAQDAEgwRgIhANRNmPtV
87
ATw4FYVuGXESDyBU6d07gkcUsEUeVY0dD95WAiEAqBns/Pr3MX8RD1bLGriQduHO
88
tJ1FJKvWpvaSEbb6VRUwDQYJKoZIhvcNAQEFBQADggEBAJj9TEgvOyp7fqaAIUK5
89
bWkRbGCsSbUxNW4yxZxNjXwIvoI89IQwGydZkqRX7//fiKEW7iMFWN6nQXxrHKfQ
90
46DQdN8WgnLf2CqJZN3kwQrJdhsV+DJrplMJXN96QFrRXgM/BCC4e2h2dryJYsDE
91
2JKKUuU6s2DhZMJ/qnyrrFTnmTQeYwIwWdcC6txdZl3VZv+EbCZEHQDUpFvdQVmR
92
kasn+9reKda5JGTuBl22OHsF+5WWHL2nYM2Fnv1sRFOWzQfQFcIVcWbl1OdUV6SQ
93
cQRRhHyM6jwWBsVJxP5H/1byHeXZTvDRl6EaU5RRCoFZEaqWPD24X+8SRkkgkV9Y
94
n64=
95
-----END CERTIFICATE-----
96
CERT
97
98
push @certificates, <<'CERT';
99
-----BEGIN CERTIFICATE-----
100
MIIG0jCCBbqgAwIBAgIQB2T3ui0CFx+cSA3+e2W7bzANBgkqhkiG9w0BAQUFADB3
101
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
102
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
103
IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTUwNDIyMDAwMDAwWhcNMTUxMDMx
104
MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
105
AhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
106
VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEERQKOTUxMzEtMjAyMTET
107
MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFjAUBgNVBAkU
108
DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoUDFBheVBhbCwgSW5jLjEUMBIGA1UECxQL
109
Q0ROIFN1cHBvcnQxFzAVBgNVBAMUDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
110
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPisQKaRu+4RFWHn4T5QUeeoQ0H5U6KXTdXp
111
EfjvdCDhAJQjDA4qwHw514zBcgrVIV/c22yUsr+RBnBYZ/rdlCiZGPT0kVYal9ts
112
XJyBFfvS3q2XMAzBg5I171geP7G46VbMBXfVkAoH1zND7O7AcNjb7z44oJgELvym
113
almQzTrfmN7RPjosfGJrQzCnMATT0Up94yIt1Imv5yCavWrIY1ImcuSjUMxTHaRy
114
D3jtnp2aBC+jhfoZYJ8a2uM6+j5h0gYpaEsLq5ilFWpvsHoKa1ZQit2/p/yE9+6U
115
oCAuJHYJRicHMNv3EdZMt7xVi5MKFCX7H+ZOmHHuZidDeL0gUQIDAQABo4ICxDCC
116
AsAwbgYDVR0RBGcwZYIMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghRkZXZl
117
bG9wZXIucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5j
118
b22CDnd3dy5wYXlwYWwuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0G
119
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG
120
+EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUG
121
CCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaA
122
FEv6LeTuMzLi3w0BoYbToDs6uayuMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
123
dC5zeW1jYi5jb20vc3QuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT
124
aHR0cDovL3N0LnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3N0LnN5bWNi
125
LmNvbS9zdC5jcnQwggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdgCkuQmQtBhYFIe7
126
E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAUzjP5slAAAEAwBHMEUCIFvjUjcbhLRI
127
0c2PUzTVMSItRsGRsoZqdz433/3MnXilAiEA3paAILaCCR6OSp/H7js1R4IxsdCx
128
Y/d9UhzFxUFevxoAdQBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ3QAA
129
AUzjP5waAAAEAwBGMEQCICcbFi1Lzw4R+ptZUnTBHJGRSTUUjptEljDAVNZmI7Xi
130
AiAM/Gly9qoF18kqaPIRZIibSoh+JnYYFuTpec2vNi12XzANBgkqhkiG9w0BAQUF
131
AAOCAQEAoUACGhsYuAMEt+420Y+q97KpGBGfRDw+5mJFuER1e3p69KAsFZRBufJb
132
BjJCbY3yWgqnNTvF+klDvok499g8I51+3fo/wdROX+fyeor+0W8Nv7Q/tNQ3J5gZ
133
CaoNT4yYOdT2wyswOzHLaQJhNNcTlbxy0lEh3f3S04MnhpB4jVCakRvORlU0FD2R
134
G4oHGhNJqthJc54f5yvlvhXi5ac9hHd8n+G86dS6QI/QWvkg2EXm0/6huSLP2Bvt
135
z6CSbS+tefVGVei0hvFvlM/ZVkaWGyJvQXli9MnQd1Fh+CkhGgOJSaGJ2/PM47zz
136
Gp3OLqh4jMEbNLobkIdLkZ2F9jYMDw==
137
-----END CERTIFICATE-----
138
CERT
139
140
# added to 0.17 on 2015.10.02
141
push @certificates, <<'CERT';
142
-----BEGIN CERTIFICATE-----
143
MIIHTTCCBjWgAwIBAgIQf8Ays2+fnhrB7auXE2UpNTANBgkqhkiG9w0BAQsFADB3
144
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
145
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
146
IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwOTAyMDAwMDAwWhcNMTcxMDMw
147
MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
148
AgwIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
149
VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEEQwKOTUxMzEtMjAyMTET
150
MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIU2FuIEpvc2UxFjAUBgNVBAkM
151
DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoMDFBheVBhbCwgSW5jLjEUMBIGA1UECwwL
152
Q0ROIFN1cHBvcnQxFzAVBgNVBAMMDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
153
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3G8cYNqcMviCcnf9UYBZa9vFajZNbopJg951
154
H5DLtlO5PEK5HLVTr1CIjeiof6amHw0h1FxvDDN+OhlY2V0B0wji0llUqcerTcb/
155
BaYLv7YREjTq1yPOPmAhvv7N22Ucr2KWPnO9CAVu6jMe1VnCcaXlIs7QF6XSrHzc
156
6ui6cBaL5ZBsfKC0eXNQXiaIo1/4R2NzUmIfxuLq9fYhQF3yGfJzBSU572/PoITp
157
pO9XrGwlzXx81DQkIAfdDQlFvZip7oPV8osFoik3DPRiF8InV53jA+OrAp36yf+B
158
FqsqlJs+BLd4L+l9djsihbZFn0JVNirLSQrA+7gPW4XRhyYb6QIDAQABo4IDPzCC
159
AzswbgYDVR0RBGcwZYIMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghRkZXZl
160
bG9wZXIucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5j
161
b22CDnd3dy5wYXlwYWwuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0G
162
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG
163
+EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUG
164
CCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaA
165
FAFZq+fdOgtZpmRj1s8gB1fVkedqMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
166
ci5zeW1jYi5jb20vc3IuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT
167
aHR0cDovL3NyLnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3NyLnN5bWNi
168
LmNvbS9zci5jcnQwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB2AKS5CZC0GFgU
169
h7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABT5BxKnwAAAQDAEcwRQIhALSBH+ef
170
tqIGyQuTuyGHJ2UFAS1mQGQUHxNt8UuakU9TAiA3Fw34Zr39bP5VYi3NvHkLCj+B
171
kc7VhicRoRhiV1TrjwB2AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+UmFXWidDd
172
AAABT5BxKtsAAAQDAEcwRQIhAOiqWJCHdJZc+2kog+8uQNVX/1qEZWUuJ0xMkeUU
173
sb/4AiAPE2v5U5jJrIGgCVLdhQe31YNw32iWoU38gAPsaIhftQB2AGj2mPgfZIK+
174
OozuuSgdTPxxUV1nk9RE0QpnrLtPT/vEAAABT5BxKnEAAAQDAEcwRQIhALUKK1wh
175
kGZHnBKN1FyOmFs1SI0MuXeyNrvuDGJ/BD28AiBays0D+G2vJXUVC6SVR5oEJEnL
176
eRiHwSh1XUc3RQYbazANBgkqhkiG9w0BAQsFAAOCAQEAm4EBf+YSO2RRvyX/Gvks
177
jxHsFVvIfKF8y7k3pKqL5RWuH8wub+qg0CKXBK40uMF47mcG4o7cKEjY3Wrxruu6
178
uO8bG23u9Pnzky9I1wXHCElCW5ja/MZ+oKvIxfYLbBtfQ1aLkD73xyP1qMQh+oBw
179
jtn19UGev1qLvOrmyugKDVjcsaP9WD1M3WUcQxPpOJ9Dx3KyGe8qUuOH1GPpWjfr
180
3iHPxRDtcejvdKLWvB/K2lCfef8TXSja+a5ml0ATYNQDRJwmZFzobM/GLrl4modk
181
JdIGuJhwGjvYvVfglJ+dXEFcThb76lJ1/A3p5ieSNpPCjIBAK0To1RS/RRiNWcfI
182
nA==
183
-----END CERTIFICATE-----
184
CERT
185
186
# added to 0.18 on 2016.08.02
187
push @certificates, <<'CERT';
188
-----BEGIN CERTIFICATE-----
189
MIIHWTCCBkGgAwIBAgIQLNGVEFQ30N5KOSAFavbCfzANBgkqhkiG9w0BAQsFADB3
190
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
191
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
192
IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwMjAyMDAwMDAwWhcNMTcxMDMw
193
MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
194
AgwIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
195
VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEEQwKOTUxMzEtMjAyMTET
196
MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIU2FuIEpvc2UxFjAUBgNVBAkM
197
DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoMDFBheVBhbCwgSW5jLjEUMBIGA1UECwwL
198
Q0ROIFN1cHBvcnQxFzAVBgNVBAMMDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
199
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2kPIs6YzXYPAYxRH/Wsivb9Op0MRVesgi+Rh
200
E+7efsbiRTSjol9+SV5RN5pKFfOnvpgbAUQUGPu6cLI5PYdFuLUG6NGxkYQGRk8R
201
+90ma7lNae+aFN19jfKHAtAQXXZQPeyj7XKTYmNKidkvU14V5G6fcD25BBkrlUfB
202
9/HnkxqEiBdAdzC8g1YioT46cPv/gQ44JfAQDYKEZAUEvTCDxQhtJLkZRh47mwJK
203
fm7M3+6yx/GMNu7tYrVUkGdPmhRmjbly9NSbh5SAjDDvLkC0ldGqotXuRI5+doaS
204
6+v1d6JT/6S2eR5tP59+XtexehUAxQFptRAWpYX4/QeEmskUkQIDAQABo4IDSzCC
205
A0cwfAYDVR0RBHUwc4ISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5jb22C
206
DGMucGF5cGFsLmNvbYINYzYucGF5cGFsLmNvbYIUZGV2ZWxvcGVyLnBheXBhbC5j
207
b22CDHAucGF5cGFsLmNvbYIOd3d3LnBheXBhbC5jb20wCQYDVR0TBAIwADAOBgNV
208
HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGYGA1Ud
209
IARfMF0wWwYLYIZIAYb4RQEHFwYwTDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5
210
bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGRoXaHR0cHM6Ly9kLnN5bWNiLmNvbS9y
211
cGEwHwYDVR0jBBgwFoAUAVmr5906C1mmZGPWzyAHV9WR52owKwYDVR0fBCQwIjAg
212
oB6gHIYaaHR0cDovL3NyLnN5bWNiLmNvbS9zci5jcmwwVwYIKwYBBQUHAQEESzBJ
213
MB8GCCsGAQUFBzABhhNodHRwOi8vc3Iuc3ltY2QuY29tMCYGCCsGAQUFBzAChhpo
214
dHRwOi8vc3Iuc3ltY2IuY29tL3NyLmNydDCCAXwGCisGAQQB1nkCBAIEggFsBIIB
215
aAFmAHYA3esdK3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbsvswAAAFSpFZ5PQAA
216
BAMARzBFAiB6j3nYN/CojD81wKOoDOhcUiK0EU32KilH3synHO5XEwIhAM2eM8Ws
217
vGK6rfGe8nJ4fGs9QMmXI3bTnRxcdWSeCem7AHUApLkJkLQYWBSHuxOizGdwCjw1
218
mAT5G9+443fNDsgN3BAAAAFSpFZ5bgAABAMARjBEAiApYKfEn4BLd4uZERNZ9/4e
219
w3NlCcoN9KcCVKesPx7OKwIgEyKaNe98YBdY9b4nw+KcJRzjZZIFJVIu7R53cfO1
220
wv4AdQBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVKkVnlXAAAE
221
AwBGMEQCIHQpjXQ06MfOV9DjzEnQm2CLPnui8P/lLyZrM6sEZvCNAiAziNOuyunX
222
wsaILVE7FMjg96sY02A0dsW/mGVPps7lJDANBgkqhkiG9w0BAQsFAAOCAQEAS6lk
223
IMx3CzCraVDTf97cfOL7k4T9eKcG6BQDmcDkSu/DXRUqgaG5/9w6r82A8HyPjh1X
224
BWlw0Zr6JZ87V8IxdYV/UQWKQLRnnEp9yaRT/4f/fbS9ObsQH3YmMbLDs2I2zAIB
225
ZdZuwaOv/PAR29XusH8fY//HNR2I2wTXGg8Ztpad6KT9gIqFfHvfSZ8VDSU9IdjN
226
fDlUABWAm1B+nDxoZWlyvHHmmOgw6m4wm5ANFul1hjAWeaR/TlWd20lj7iXUt+dW
227
GN/QMQ3a55rjwNQnA3s2WWuHGPaE/jMG17iiL2O/hUdIvLE9+wA+fWrey5//74xl
228
NeQitYiySDIepHGnng==
229
-----END CERTIFICATE-----
230
CERT
231
232
# added to 0.19 on 2020.03.07
233
push @certificates, <<'CERT';
234
-----BEGIN CERTIFICATE-----
235
MIIHmTCCBoGgAwIBAgIQDsNOdwJXAE+tzPSi9RnWDDANBgkqhkiG9w0BAQsFADB1
236
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
237
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
238
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTIwMDEwOTAwMDAwMFoXDTIyMDExMjEy
239
MDAwMFowgdwxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
240
BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF
241
EwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8G
242
A1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFBheVBhbCwgSW5jLjEUMBIGA1UECxML
243
Q0ROIFN1cHBvcnQxFzAVBgNVBAMTDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
244
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq5rER+ZPS/B6KW+aHWtO1QQOsgLtjdGprtXa
245
IIx+ikkaPAkT93LuLkDgKUECeJdV+AYNeyrj4LPlZPLeuLg14cV86xLjaEd0bLwE
246
JTMJFyjgyTqyTmVQ0ErkO7LhLoJFy1IFO6S3N+vIKfxDZ8xmqeWfIhsb94Y2NZtF
247
9Q9sPR0VVV3+yn1c7x12t/BZhYkaydK/WLwmnBF1YMtZ5nQY7g4GvFShR/n1tcC+
248
rW3u3Zm2UO2FM/W9k0tmqQjwZ8e9QiTCO+N/8eJRYrVRriGoJNnJ7dO0YBdqDHhp
249
wZatYh0YEabq9IPrLa6wvi5Wnc+dLHBa37IeOsfkI+M7WOH9nQIDAQABo4IDuzCC
250
A7cwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFPAe
251
9ePuM1NpVGonQODOhLZpaEueMGcGA1UdEQRgMF6CDnd3dy5wYXlwYWwuY29tghBs
252
b2dpbi5wYXlwYWwuY29tghJoaXN0b3J5LnBheXBhbC5jb22CFXd3dy5wYXlwYWxv
253
YmplY3RzLmNvbYIPcGljcy5wYXlwYWwuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNV
254
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0
255
cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNybDA0oDKg
256
MIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcyLmNy
257
bDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsGAQUFBwIBFhxodHRwczov
258
L3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEFBQcBAQR8MHow
259
JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEFBQcw
260
AoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4dGVu
261
ZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMIIBfgYKKwYB
262
BAHWeQIEAgSCAW4EggFqAWgAdwCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80O
263
yA3cEAAAAW+Hv9N9AAAEAwBIMEYCIQD22HBv3vOh3xDflHjmJ5ipfGDRwgl9Od4Y
264
5kvUeff7AAIhAKW5E/P2aatw3NDzrR/v+k9XDjgAbEioeJmcjDKUlyEkAHYAVhQG
265
mi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFvh7/UXwAABAMARzBFAiEA
266
/5GV9keLQVjAvRlzi5+YoFzymiQiKvJkD0i33kAijdwCIEuaqfF5owFlEMq8/CT1
267
Cp2aGgUQ8C4M78yprySEEymgAHUA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7
268
iXqo/csAAAFvh7/TxQAABAMARjBEAiAI/pmrL76VNgjgI/f6De5QokYAUdP0inWM
269
dGICpFNcigIgE4pM5uLHDTg560kp1CNDTPpLAYzS28t/OUyEFOSk3SQwDQYJKoZI
270
hvcNAQELBQADggEBAJUGjFwcOaoZMwxwWH+UK6RxvvcTTiNz8Kh8NRYO4r5ZVj2M
271
XfqM+93ejjSjarOGWylSSl/3yx8zuMhgOzBylPxh312AL/mPrfOFmCro7WwC4T7Q
272
zO9oNk6uUW3KLnuuo3k9J2d0FU3PyR2h+UNpzmay6+zEMUgn2S3i6/RyCnMj0Zxd
273
jjSylaOoCRbOL7/R+Ee9wW02fjqcWMFHQJKOtjKXiV77RsM9LAZGI4YqbNI6GD46
274
K/zDOsAXakwy9dKoqaNfKlPJv4ifD8Z0Y32DF0lgctLLybgCWPfZ8Dz+H03760Og
275
+lieGRy3bEXsDLkNSgm+dmg1SGJcgjyA5Od7Zvc=
276
-----END CERTIFICATE-----
277
CERT
278
279
# CERT
280
# added to 0.20 on 2020.11.24
281
# openssl x509 -in cert.txt -text -noout says:
282
# Not Before: Mar 10 00:00:00 2020 GMT
283
# Not After : Mar 15 12:00:00 2022 GMT
284
push @certificates, <<'CERT';
285
-----BEGIN CERTIFICATE-----
286
MIIHdDCCBlygAwIBAgIQB0Haxhm5e7comqWUzibAzTANBgkqhkiG9w0BAQsFADB1
287
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
288
d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
289
IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTIwMDMxMDAwMDAwMFoXDTIyMDMxNTEy
290
MDAwMFowgdwxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
291
BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF
292
EwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8G
293
A1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFBheVBhbCwgSW5jLjEUMBIGA1UECxML
294
Q0ROIFN1cHBvcnQxFzAVBgNVBAMTDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG
295
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzV89zboBlCiAoOYvIuxNozHpQYGRrKI2f3JH
296
uJL4wWc+v80i1jvWglmQnI7gBrA9eoB5qSMHU3+f3ubXqwO5teSn5UYasemZw4wP
297
pfU5w5iviSn7xuDK748x9IRXu6kyCMT/NnLLAE/wuVaNnTK8PZG50UKNicN3R1i6
298
noAWphNJe98stO4CjD1YX6qUkCID2QRNaewR/q3GPZcXyYGpovabx4JBCAfoyrwX
299
7MMSashX/HcapZO3wbsF+tO3GE1ZIuTxm3QHYDvDTkUbPtft7S5ggv5Wt9UUYC3P
300
ieLtJFBED3zCiFjWNv97H/ozZdlWC27GHSnfh4OFqNynOta4kwIDAQABo4IDljCC
301
A5IwHwYDVR0jBBgwFoAUPdNQpdagre7zSmAKZdMh1Pj41g8wHQYDVR0OBBYEFKdH
302
mNESeNtRMvqNvx0ubsMOzcztMEAGA1UdEQQ5MDeCDnd3dy5wYXlwYWwuY29tghF3
303
d3ctc3QucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tMA4GA1UdDwEB/wQE
304
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0
305
oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVyLWcy
306
LmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYtc2Vy
307
dmVyLWcyLmNybDBLBgNVHSAERDBCMDcGCWCGSAGG/WwCATAqMCgGCCsGAQUFBwIB
308
FhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAcGBWeBDAEBMIGIBggrBgEF
309
BQcBAQR8MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBS
310
BggrBgEFBQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
311
U0hBMkV4dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAA
312
MIIBgAYKKwYBBAHWeQIEAgSCAXAEggFsAWoAdwDuS723dc5guuFCaR+r4Z5mow9+
313
X7By2IMAxHuJeqj9ywAAAXDFcnb8AAAEAwBIMEYCIQDwuzYl2COuAY6OhOQOkKHF
314
wydBzAHq0nfq+sjx4pMShgIhAMupFpT63PmXJRf9yYmAawHFYfJG42Am1LKIfjcx
315
OdRQAHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFwxXJ3HgAA
316
BAMASDBGAiEA9sLqzoClOirtBp0Hi2EbFPMoNsagZ5KJ1lNm1FZrAdcCIQDbXiRH
317
/kFOqNmaszNY/CVCeZaezHyWrDj3piruCc4VEAB2ALvZ37wfinG1k5Qjl6qSe0c4
318
V5UKq1LoGpCWZDaOHtGFAAABcMVydsAAAAQDAEcwRQIgMAg0E301jaPus8jRHECx
319
3EB4dmx9i9YGmpm/ewljFBoCIQDtdorg7IAj58ZOUNtassnYFj4cshHP8HqAx0ds
320
JzngzDANBgkqhkiG9w0BAQsFAAOCAQEALew4jcCp55VpcnPhSzHQSpOV3oHCu1BX
321
eRgvHLk2sgFs+DFHjyTnhPlozShKhvgksPMO3BhNGCvYqXNubiFDIJSnM9l8p4d8
322
JY0JTV/kt5GR5S0h+zyHYNpfDw+zBCS8TjJf4zmGNY1VulJy9JEikJXOqvzAn+uy
323
7KKXZnjYHoPMJkSJ8iH8FF5C3s8mbfmFjYM1RWSS44pdezTfJJ/mmjpSMyclihBX
324
K1vmFTxDQaxtLhisYbNd5hxxDw2oZTYibruc4ELBmJZBbryicaBSbmB4pVFCC5Jf
325
ykI2dP/TyTCxV+Wy++cjjAUehq19e/LdQ2orgofqpAFKjqT1nSkteA==
326
-----END CERTIFICATE-----
327
CERT
328
329
330
chomp(@certificates);
331
332
my @cert_contents;
333
push @cert_contents, <<'CERTCONTENT';
334
Subject Name: /1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com
335
Issuer Name: /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL CA
336
CERTCONTENT
337
338
push @cert_contents, <<'CERTCONTENT';
339
Subject Name: /1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com
340
Issuer Name: /C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G2
341
CERTCONTENT
342
343
# added to 0.17 on 2015.10.02
344
push @cert_contents, <<'CERTCONTENT';
345
Subject Name: /1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com
346
Issuer Name: /C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3
347
CERTCONTENT
348
349
# added to 0.19 on 2020.03.07
350
push @cert_contents, <<'CERTCONTENT';
351
Subject Name: /businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Delaware/serialNumber=3014267/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com
352
Issuer Name: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA
353
CERTCONTENT
354
355
chomp(@cert_contents);
356
357
# creates new PayPal object. Assigns an id if none is provided.
358
sub new {
359
4
4
1
11480
my $class = shift;
360
361
4
19
my $self = {
362
id => undef,
363
address => 'https://www.paypal.com/cgi-bin/webscr',
364
check_cert => 1,
365
@_,
366
};
367
4
10
bless $self, $class;
368
4
100
91
$self->{id} = md5_hex(rand()) unless $self->{id};
369
370
4
13
return $self;
371
}
372
373
sub check_cert {
374
2
2
0
3681
my ($self, $value) = @_;
375
2
8
$self->{check_cert} = $value;
376
2
6
return;
377
}
378
379
# returns current PayPal id
380
sub id {
381
2
2
1
1640
my ($self) = @_;
382
383
2
6
return $self->{id};
384
}
385
386
#creates a PayPal button
387
sub button {
388
3
3
1
682
my $self = shift;
389
390
my %buttonparam = (
391
cmd => '_ext-enter',
392
redirect_cmd => '_xclick',
393
button_image => qq{ },
394
business => undef,
395
item_name => undef,
396
item_number => undef,
397
image_url => undef,
398
no_shipping => 1,
399
return => undef,
400
cancel_return => undef,
401
no_note => 1,
402
undefined_quantity => 0,
403
notify_url => undef,
404
first_name => undef,
405
last_name => undef,
406
shipping => undef,
407
shipping2 => undef,
408
quantity => undef,
409
amount => undef,
410
address1 => undef,
411
address2 => undef,
412
city => undef,
413
state => undef,
414
zip => undef,
415
night_phone_a => undef,
416
night_phone_b => undef,
417
night_phone_c => undef,
418
day_phone_a => undef,
419
day_phone_b => undef,
420
day_phone_c => undef,
421
receiver_email => undef,
422
invoice => undef,
423
currency_code => undef,
424
custom => $self->{id},
425
3
78
@_,
426
);
427
3
14
my $key;
428
3
5
my $form_id = '';
429
3
100
11
if (defined $buttonparam{form_id}) {
430
1
5
$form_id = qq{id="$buttonparam{form_id}"};
431
1
2
delete $buttonparam{form_id};
432
}
433
3
15
my $content = qq{
434
435
3
50
foreach my $param (sort keys %buttonparam) {
436
106
100
222
next if not defined $buttonparam{$param};
437
38
100
67
next if $param eq 'button_image';
438
35
79
$content .= qq{ \n};
439
}
440
3
21
$content .= "$buttonparam{button_image}\n";
441
3
5
$content .= qq{\n};
442
443
3
23
return $content;
444
}
445
446
447
# takes a reference to a hash of name value pairs, such as from a CGI query
448
# object, which should contain all the name value pairs which have been
449
# posted to the script by PayPal's Instant Payment Notification
450
# posts that data back to PayPal, checking if the ssl certificate matches,
451
# and returns success or failure, and the reason.
452
sub ipnvalidate {
453
3
3
1
1336
my ($self, $query) = @_;
454
455
3
10
$query->{cmd} = '_notify-validate';
456
3
8
my $id = $self->{id};
457
3
11
my ($succ, $reason) = $self->postpaypal($query);
458
459
3
0
11
return (wantarray ? ($id, $reason) : $id ) if $succ;
50
460
3
100
23
return (wantarray ? (undef, $reason) : undef);
461
}
462
463
# this method should not normally be used unless you need to test, or if
464
# you are overriding the behaviour of ipnvalidate. It takes a reference
465
# to a hash containing the query, posts to PayPal with the data, and returns
466
# success or failure, as well as PayPal's response.
467
sub postpaypal {
468
3
3
1
8
my ($self, $query) = @_;
469
470
3
10
my $address = $self->{address};
471
3
7
my ($site, $port, $path);
472
473
#following code splits an url into site, port and path components
474
3
15
my @address = split /:\/\//, $address, 2;
475
3
19
@address = split /(?=\/)/, $address[1], 2;
476
3
50
15
if ($address[0] =~ /:/) {
477
0
0
($site, $port) = split /:/, $address[0];
478
}
479
else {
480
3
10
($site, $port) = ($address[0], '443');
481
}
482
3
6
$path = $address[1];
483
3
67
my ($page,
484
$response,
485
$headers,
486
$ppcert,
487
) = Net::SSLeay::post_https3($site,
488
$port,
489
$path,
490
'',
491
Net::SSLeay::make_form(%$query));
492
493
3
0
2752468
return (wantarray ? (undef, "No PayPal cert found") : undef)
50
494
unless $ppcert;
495
496
3
128
my $ppx509 = Net::SSLeay::PEM_get_string_X509($ppcert);
497
3
87
my $ppcertcontent =
498
'Subject Name: '
499
. Net::SSLeay::X509_NAME_oneline(
500
Net::SSLeay::X509_get_subject_name($ppcert))
501
. "\nIssuer Name: "
502
. Net::SSLeay::X509_NAME_oneline(
503
Net::SSLeay::X509_get_issuer_name($ppcert))
504
. "\n";
505
506
3
12
chomp $ppx509;
507
3
9
chomp $ppcertcontent;
508
509
3
19
my @certs = @certificates;
510
3
50
13
if ($Cert) {
511
# TODO added in 0.12
512
0
0
warn "The global variable \$Cert is deprecated and will be removed soon. Pass a certificate to the constructor using the 'cert' parameter.\n";
513
0
0
push @certs, $Cert;
514
}
515
3
13
my @cert_cont = @cert_contents;
516
3
50
11
if ($Certcontent) {
517
# TODO added in 0.12
518
0
0
warn "The global variable \$Certcontent is deprecated and will be removed soon. Pass a certificate to the constructor using the 'certcontent' parameter.\n";
519
0
0
push @cert_cont, $Certcontent;
520
}
521
522
3
50
16
if ($self->{addcert}) {
523
0
0
push @certs, $self->{cert};
524
}
525
3
50
14
if ($self->{addcertcontent}) {
526
0
0
push @cert_cont, $self->{certcontent};
527
}
528
529
3
50
15
if ($self->{cert}) {
530
0
0
@certs = $self->{cert};
531
}
532
3
50
11
if ($self->{certcontent}) {
533
0
0
@cert_cont = $self->{certcontent};
534
}
535
536
3
100
9
if ($self->{check_cert}) {
537
return (wantarray ? (undef, "PayPal cert failed to match:\n$ppx509") : undef)
538
2
0
8
unless grep {$_ eq $ppx509} @certs;
14
50
36
539
return (wantarray ? (undef, "PayPal cert contents failed to match:\n$ppcertcontent") : undef)
540
2
0
6
unless grep { $_ eq $ppcertcontent } @cert_cont;
8
50
20
541
}
542
3
50
34
return (wantarray ? (undef, 'PayPal says transaction INVALID') : undef)
50
543
if $page eq 'INVALID';
544
0
0
return (wantarray ? (1, 'PayPal says transaction VERIFIED') : 1)
0
545
if $page eq 'VERIFIED';
546
0
warn "Bad stuff happened\n$page";
547
0
0
return (wantarray ? (undef, "Bad stuff happened") :undef);
548
}
549
550
551
552
1;
553
554
=head1 NAME
555
556
Business::PayPal - Perl extension for automating PayPal transactions
557
558
=head1 ABSTRACT
559
560
Business::PayPal makes the automation of PayPal transactions as simple
561
as doing credit card transactions through a regular processor. It includes
562
methods for creating PayPal buttons and for validating the Instant Payment
563
Notification that is sent when PayPal processes a payment.
564
565
=head1 SYNOPSIS
566
567
To generate a PayPal button for use on your site
568
Include something like the following in your CGI
569
570
use Business::PayPal;
571
my $paypal = Business::PayPal->new;
572
my $button = $paypal->button(
573
business => 'dr@dursec.com',
574
item_name => 'CanSecWest Registration Example',
575
return => 'http://www.cansecwest.com/return.cgi',
576
cancel_return => 'http://www.cansecwest.com/cancel.cgi',
577
amount => '1600.00',
578
quantity => 1,
579
notify_url => http://www.cansecwest.com/ipn.cgi
580
);
581
my $id = $paypal->id;
582
583
Store $id somewhere so we can get it back again later
584
585
Store current context with $id.
586
587
Print button to the browser.
588
589
Note, button is an HTML form, already enclosed in tags
590
591
592
593
To validate the Instant Payment Notification from PayPal for the
594
button used above include something like the following in your
595
'notify_url' CGI.
596
597
use CGI;
598
my $query = CGI->new;
599
my %query = $query->Vars;
600
my $id = $query{custom};
601
my $paypal = Business::PayPal->new(id => $id);
602
my ($txnstatus, $reason) = $paypal->ipnvalidate(\%query);
603
die "PayPal failed: $reason" unless $txnstatus;
604
my $money = $query{payment_gross};
605
my $paystatus = $query{payment_status};
606
607
Check if paystatus eq 'Completed'.
608
Check if $money is the amount you expected.
609
Save payment status information to store as $id.
610
611
612
To tell the user if their payment succeeded or not, use something like
613
the following in the CGI pointed to by the 'return' parameter in your
614
PayPal button.
615
616
use CGI;
617
my $query = CGI->new;
618
my $id = $query{custom};
619
620
#get payment status from store for $id
621
#return payment status to customer
622
623
In order to use the sandbox provided by PayPal, you can provide the address of the sandbox
624
in the constructor:
625
626
my $pp = Business::PayPal->new( address => 'https://www.sandbox.paypal.com/cgi-bin/webscr' );
627
628
=head1 DESCRIPTION
629
630
=head2 new()
631
632
Creates a new Business::PayPal object, it can take the
633
following parameters:
634
635
=over 2
636
637
=item id
638
639
The Business::PayPal object id, if not specified a new
640
id will be created using md5_hex(rand())
641
642
=item address
643
644
The address of PayPal's payment server, currently:
645
https://www.paypal.com/cgi-bin/webscr
646
647
=item cert
648
649
The x509 certificate for I, see source for default.
650
651
=item certcontent
652
653
The contents of the x509 certificate I, see source for
654
default.
655
656
=item addcert
657
658
The x509 certificate for I.
659
This is added to the default values.
660
661
=item addcertcontent
662
663
The contents of the x509 certificate I,
664
This is added to the default values.
665
666
=back
667
668
=head2 id()
669
670
Returns the id for the Business::PayPal object.
671
672
=head2 button()
673
674
Returns the HTML for a PayPal button. It takes a large number of
675
parameters, which control the look and function of the button, some
676
of which are required and some of which have defaults. They are
677
as follows:
678
679
=over 2
680
681
=item cmd
682
683
required, defaults to '_ext-enter'
684
685
This allows the user information to be pre-filled in.
686
You should never need to specify this, as the default should
687
work fine.
688
689
=item redirect_cmd
690
691
required, defaults to '_xclick'
692
693
This allows the user information to be pre-filled in.
694
You should never need to specify this, as the default should
695
work fine.
696
697
=item button_image
698
699
required, defaults to:
700
701
CGI::image_button(-name => 'submit',
702
-src => 'http://images.paypal.com/x-click-but01.gif'
703
-alt => 'Make payments with PayPal',
704
)
705
706
You may wish to change this if the button is on an https page
707
so as to avoid the browser warnings about insecure content on a
708
secure page.
709
710
for example use a Bootstrap style button:
711
712
button_image => '9 USD per month ',
713
714
=item form_id
715
716
form_id => 'some_id',
717
718
Adding id="some_id" to the form created. Adding and id will make it easier to locate
719
the form on the page by some JavaScript code.
720
721
=item business
722
723
required, no default
724
725
This is the name of your PayPal account.
726
727
=item item_name
728
729
This is the name of the item you are selling.
730
731
=item item_number
732
733
This is a numerical id of the item you are selling.
734
735
=item image_url
736
737
A URL pointing to a 150 x 50 image which will be displayed
738
instead of the name of your PayPal account.
739
740
=item no_shipping
741
742
defaults to 1
743
744
If set to 1, does not ask customer for shipping info, if
745
set to 0 the customer will be prompted for shipping information.
746
747
=item return
748
749
This is the URL to which the customer will return to after
750
they have finished paying.
751
752
=item cancel_return
753
754
This is the URL to which the customer will be sent if they cancel
755
before paying.
756
757
=item no_note
758
759
defaults to 1
760
761
If set to 1, does not ask customer for a note with the payment,
762
if set to 0, the customer will be asked to include a note.
763
764
=item currency_code
765
766
Currency the payment should be taken in, e.g. EUR, GBP.
767
If not specified payments default to USD.
768
769
=item address1
770
771
=item undefined_quantity
772
773
defaults to 0
774
775
If set to 0 the quantity defaults to 1, if set to 1 the user
776
can edit the quantity.
777
778
=item notify_url
779
780
The URL to which PayPal Instant Payment Notification is sent.
781
782
=item first_name
783
784
First name of customer, used to pre-fill PayPal forms.
785
786
=item last_name
787
788
Last name of customer, used to pre-fill PayPal forms.
789
790
=item shipping
791
792
I don't know, something to do with shipping, please tell me if
793
you find out.
794
795
=item shipping2
796
797
I don't know, something to do with shipping, please tell me if you
798
find out.
799
800
=item quantity
801
802
defaults to 1
803
804
Number of items being sold.
805
806
=item amount
807
808
Price of the item being sold.
809
810
=item address1
811
812
Address of customer, used to pre-fill PayPal forms.
813
814
=item address2
815
816
Address of customer, used to pre-fill PayPal forms.
817
818
=item city
819
820
City of customer, used to pre-fill PayPal forms.
821
822
=item state
823
824
State of customer, used to pre-fill PayPal forms.
825
826
=item zip
827
828
Zip of customer, used to pre-fill PayPal forms.
829
830
=item night_phone_a
831
832
Phone
833
834
=item night_phone_b
835
836
Phone
837
838
=item night_phone_c
839
840
Phone
841
842
=item day_phone_a
843
844
Phone
845
846
=item day_phone_b
847
848
Phone
849
850
=item day_phone_c
851
852
Phone
853
854
=item receiver_email
855
856
Email address of customer - I think
857
858
=item invoice
859
860
Invoice number - I think
861
862
=item custom
863
864
defaults to the Business::PayPal id
865
866
Used by Business::PayPal to track which button is associated
867
with which Instant Payment Notification.
868
869
=back
870
871
=head2 ipnvalidate()
872
873
Takes a reference to a hash of name value pairs, such as from a
874
CGI query object, which should contain all the name value pairs
875
which have been posted to the script by PayPal's Instant Payment
876
Notification posts that data back to PayPal, checking if the ssl
877
certificate matches, and returns success or failure, and the
878
reason.
879
880
=head2 postpaypal()
881
882
This method should not normally be used unless you need to test,
883
or if you are overriding the behaviour of ipnvalidate. It takes a
884
reference to a hash containing the query, posts to PayPal with
885
the data, and returns success or failure, as well as PayPal's
886
response.
887
888
=head1 MAINTAINER
889
890
Josh Rabinowitz
891
892
Gabor Szabo, L , L
893
894
phred, Efred@redhotpenguin.comE
895
896
=head1 AUTHOR
897
898
mock, Emock@obscurity.orgE
899
900
=head1 SEE ALSO
901
902
L, L, L.
903
904
Explanation of the fields: L
905
See also in the pdf here: L
906
907
908
=head1 LICENSE
909
910
Copyright (c) 2010, phred Efred@redhotpenguin.comE. All rights reserved.
911
912
Copyright (c) 2002, mock Emock@obscurity.orgE. All rights reserved.
913
914
This library is free software; you can redistribute it and/or modify
915
it under the same terms as Perl itself.
916
917
=cut