File Coverage

blib/lib/Business/PayPal.pm
Criterion Covered Total %
statement 73 85 85.8
branch 25 52 48.0
condition n/a
subroutine 11 11 100.0
pod 5 6 83.3
total 114 154 74.0


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{
\n};
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 => '',
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