├── .gitignore ├── Build.PL ├── Changes ├── LICENSE ├── META.json ├── README.md ├── cpanfile ├── dist.ini ├── lib └── Business │ └── PxPay.pm └── t ├── 00-load.t ├── 01-basic.t └── pod.t /.gitignore: -------------------------------------------------------------------------------- 1 | /Business-PxPay-* 2 | /.build 3 | /_build* 4 | /Build 5 | MYMETA.* 6 | !META.json 7 | /.prove 8 | examples/.token -------------------------------------------------------------------------------- /Build.PL: -------------------------------------------------------------------------------- 1 | # This Build.PL for Business-PxPay was generated by Dist::Zilla::Plugin::ModuleBuildTiny 0.015. 2 | use strict; 3 | use warnings; 4 | 5 | use 5.006; 6 | use Module::Build::Tiny 0.034; 7 | Build_PL(); 8 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for Business-PxPay 2 | 3 | {{$NEXT}} 4 | 5 | 0.05 2018-12-20 20:02:25 CST 6 | Added missing prereq URI::Escape (manwar) 7 | 8 | 0.04 2011.07.19 9 | API URL changed to https://sec.paymentexpress.com/pxpay/pxaccess.aspx 10 | 11 | 0.03 2010.01.29 12 | use www.paymentexpress.com by default 13 | 14 | 0.02 2009.11.18 15 | bug fix 16 | 17 | 0.01 2009.11.17 18 | First version, released on an unsuspecting world. 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is copyright (c) 2018 by Fayland Lam. 2 | 3 | This is free software; you can redistribute it and/or modify it under 4 | the same terms as the Perl 5 programming language system itself. 5 | 6 | Terms of the Perl programming language system itself 7 | 8 | a) the GNU General Public License as published by the Free 9 | Software Foundation; either version 1, or (at your option) any 10 | later version, or 11 | b) the "Artistic License" 12 | 13 | --- The GNU General Public License, Version 1, February 1989 --- 14 | 15 | This software is Copyright (c) 2018 by Fayland Lam. 16 | 17 | This is free software, licensed under: 18 | 19 | The GNU General Public License, Version 1, February 1989 20 | 21 | GNU GENERAL PUBLIC LICENSE 22 | Version 1, February 1989 23 | 24 | Copyright (C) 1989 Free Software Foundation, Inc. 25 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | 27 | Everyone is permitted to copy and distribute verbatim copies 28 | of this license document, but changing it is not allowed. 29 | 30 | Preamble 31 | 32 | The license agreements of most software companies try to keep users 33 | at the mercy of those companies. By contrast, our General Public 34 | License is intended to guarantee your freedom to share and change free 35 | software--to make sure the software is free for all its users. The 36 | General Public License applies to the Free Software Foundation's 37 | software and to any other program whose authors commit to using it. 38 | You can use it for your programs, too. 39 | 40 | When we speak of free software, we are referring to freedom, not 41 | price. Specifically, the General Public License is designed to make 42 | sure that you have the freedom to give away or sell copies of free 43 | software, that you receive source code or can get it if you want it, 44 | that you can change the software or use pieces of it in new free 45 | programs; and that you know you can do these things. 46 | 47 | To protect your rights, we need to make restrictions that forbid 48 | anyone to deny you these rights or to ask you to surrender the rights. 49 | These restrictions translate to certain responsibilities for you if you 50 | distribute copies of the software, or if you modify it. 51 | 52 | For example, if you distribute copies of a such a program, whether 53 | gratis or for a fee, you must give the recipients all the rights that 54 | you have. You must make sure that they, too, receive or can get the 55 | source code. And you must tell them their rights. 56 | 57 | We protect your rights with two steps: (1) copyright the software, and 58 | (2) offer you this license which gives you legal permission to copy, 59 | distribute and/or modify the software. 60 | 61 | Also, for each author's protection and ours, we want to make certain 62 | that everyone understands that there is no warranty for this free 63 | software. If the software is modified by someone else and passed on, we 64 | want its recipients to know that what they have is not the original, so 65 | that any problems introduced by others will not reflect on the original 66 | authors' reputations. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | GNU GENERAL PUBLIC LICENSE 72 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 73 | 74 | 0. This License Agreement applies to any program or other work which 75 | contains a notice placed by the copyright holder saying it may be 76 | distributed under the terms of this General Public License. The 77 | "Program", below, refers to any such program or work, and a "work based 78 | on the Program" means either the Program or any work containing the 79 | Program or a portion of it, either verbatim or with modifications. Each 80 | licensee is addressed as "you". 81 | 82 | 1. You may copy and distribute verbatim copies of the Program's source 83 | code as you receive it, in any medium, provided that you conspicuously and 84 | appropriately publish on each copy an appropriate copyright notice and 85 | disclaimer of warranty; keep intact all the notices that refer to this 86 | General Public License and to the absence of any warranty; and give any 87 | other recipients of the Program a copy of this General Public License 88 | along with the Program. You may charge a fee for the physical act of 89 | transferring a copy. 90 | 91 | 2. You may modify your copy or copies of the Program or any portion of 92 | it, and copy and distribute such modifications under the terms of Paragraph 93 | 1 above, provided that you also do the following: 94 | 95 | a) cause the modified files to carry prominent notices stating that 96 | you changed the files and the date of any change; and 97 | 98 | b) cause the whole of any work that you distribute or publish, that 99 | in whole or in part contains the Program or any part thereof, either 100 | with or without modifications, to be licensed at no charge to all 101 | third parties under the terms of this General Public License (except 102 | that you may choose to grant warranty protection to some or all 103 | third parties, at your option). 104 | 105 | c) If the modified program normally reads commands interactively when 106 | run, you must cause it, when started running for such interactive use 107 | in the simplest and most usual way, to print or display an 108 | announcement including an appropriate copyright notice and a notice 109 | that there is no warranty (or else, saying that you provide a 110 | warranty) and that users may redistribute the program under these 111 | conditions, and telling the user how to view a copy of this General 112 | Public License. 113 | 114 | d) You may charge a fee for the physical act of transferring a 115 | copy, and you may at your option offer warranty protection in 116 | exchange for a fee. 117 | 118 | Mere aggregation of another independent work with the Program (or its 119 | derivative) on a volume of a storage or distribution medium does not bring 120 | the other work under the scope of these terms. 121 | 122 | 3. You may copy and distribute the Program (or a portion or derivative of 123 | it, under Paragraph 2) in object code or executable form under the terms of 124 | Paragraphs 1 and 2 above provided that you also do one of the following: 125 | 126 | a) accompany it with the complete corresponding machine-readable 127 | source code, which must be distributed under the terms of 128 | Paragraphs 1 and 2 above; or, 129 | 130 | b) accompany it with a written offer, valid for at least three 131 | years, to give any third party free (except for a nominal charge 132 | for the cost of distribution) a complete machine-readable copy of the 133 | corresponding source code, to be distributed under the terms of 134 | Paragraphs 1 and 2 above; or, 135 | 136 | c) accompany it with the information you received as to where the 137 | corresponding source code may be obtained. (This alternative is 138 | allowed only for noncommercial distribution and only if you 139 | received the program in object code or executable form alone.) 140 | 141 | Source code for a work means the preferred form of the work for making 142 | modifications to it. For an executable file, complete source code means 143 | all the source code for all modules it contains; but, as a special 144 | exception, it need not include source code for modules which are standard 145 | libraries that accompany the operating system on which the executable 146 | file runs, or for standard header files or definitions files that 147 | accompany that operating system. 148 | 149 | 4. You may not copy, modify, sublicense, distribute or transfer the 150 | Program except as expressly provided under this General Public License. 151 | Any attempt otherwise to copy, modify, sublicense, distribute or transfer 152 | the Program is void, and will automatically terminate your rights to use 153 | the Program under this License. However, parties who have received 154 | copies, or rights to use copies, from you under this General Public 155 | License will not have their licenses terminated so long as such parties 156 | remain in full compliance. 157 | 158 | 5. By copying, distributing or modifying the Program (or any work based 159 | on the Program) you indicate your acceptance of this license to do so, 160 | and all its terms and conditions. 161 | 162 | 6. Each time you redistribute the Program (or any work based on the 163 | Program), the recipient automatically receives a license from the original 164 | licensor to copy, distribute or modify the Program subject to these 165 | terms and conditions. You may not impose any further restrictions on the 166 | recipients' exercise of the rights granted herein. 167 | 168 | 7. The Free Software Foundation may publish revised and/or new versions 169 | of the General Public License from time to time. Such new versions will 170 | be similar in spirit to the present version, but may differ in detail to 171 | address new problems or concerns. 172 | 173 | Each version is given a distinguishing version number. If the Program 174 | specifies a version number of the license which applies to it and "any 175 | later version", you have the option of following the terms and conditions 176 | either of that version or of any later version published by the Free 177 | Software Foundation. If the Program does not specify a version number of 178 | the license, you may choose any version ever published by the Free Software 179 | Foundation. 180 | 181 | 8. If you wish to incorporate parts of the Program into other free 182 | programs whose distribution conditions are different, write to the author 183 | to ask for permission. For software which is copyrighted by the Free 184 | Software Foundation, write to the Free Software Foundation; we sometimes 185 | make exceptions for this. Our decision will be guided by the two goals 186 | of preserving the free status of all derivatives of our free software and 187 | of promoting the sharing and reuse of software generally. 188 | 189 | NO WARRANTY 190 | 191 | 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 192 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 193 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 194 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 195 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 196 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 197 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 198 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 199 | REPAIR OR CORRECTION. 200 | 201 | 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 202 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 203 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 204 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 205 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 206 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 207 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 208 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 209 | POSSIBILITY OF SUCH DAMAGES. 210 | 211 | END OF TERMS AND CONDITIONS 212 | 213 | Appendix: How to Apply These Terms to Your New Programs 214 | 215 | If you develop a new program, and you want it to be of the greatest 216 | possible use to humanity, the best way to achieve this is to make it 217 | free software which everyone can redistribute and change under these 218 | terms. 219 | 220 | To do so, attach the following notices to the program. It is safest to 221 | attach them to the start of each source file to most effectively convey 222 | the exclusion of warranty; and each file should have at least the 223 | "copyright" line and a pointer to where the full notice is found. 224 | 225 | 226 | Copyright (C) 19yy 227 | 228 | This program is free software; you can redistribute it and/or modify 229 | it under the terms of the GNU General Public License as published by 230 | the Free Software Foundation; either version 1, or (at your option) 231 | any later version. 232 | 233 | This program is distributed in the hope that it will be useful, 234 | but WITHOUT ANY WARRANTY; without even the implied warranty of 235 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 236 | GNU General Public License for more details. 237 | 238 | You should have received a copy of the GNU General Public License 239 | along with this program; if not, write to the Free Software 240 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 241 | 242 | 243 | Also add information on how to contact you by electronic and paper mail. 244 | 245 | If the program is interactive, make it output a short notice like this 246 | when it starts in an interactive mode: 247 | 248 | Gnomovision version 69, Copyright (C) 19xx name of author 249 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 250 | This is free software, and you are welcome to redistribute it 251 | under certain conditions; type `show c' for details. 252 | 253 | The hypothetical commands `show w' and `show c' should show the 254 | appropriate parts of the General Public License. Of course, the 255 | commands you use may be called something other than `show w' and `show 256 | c'; they could even be mouse-clicks or menu items--whatever suits your 257 | program. 258 | 259 | You should also get your employer (if you work as a programmer) or your 260 | school, if any, to sign a "copyright disclaimer" for the program, if 261 | necessary. Here a sample; alter the names: 262 | 263 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 264 | program `Gnomovision' (a program to direct compilers to make passes 265 | at assemblers) written by James Hacker. 266 | 267 | , 1 April 1989 268 | Ty Coon, President of Vice 269 | 270 | That's all there is to it! 271 | 272 | 273 | --- The Artistic License 1.0 --- 274 | 275 | This software is Copyright (c) 2018 by Fayland Lam. 276 | 277 | This is free software, licensed under: 278 | 279 | The Artistic License 1.0 280 | 281 | The Artistic License 282 | 283 | Preamble 284 | 285 | The intent of this document is to state the conditions under which a Package 286 | may be copied, such that the Copyright Holder maintains some semblance of 287 | artistic control over the development of the package, while giving the users of 288 | the package the right to use and distribute the Package in a more-or-less 289 | customary fashion, plus the right to make reasonable modifications. 290 | 291 | Definitions: 292 | 293 | - "Package" refers to the collection of files distributed by the Copyright 294 | Holder, and derivatives of that collection of files created through 295 | textual modification. 296 | - "Standard Version" refers to such a Package if it has not been modified, 297 | or has been modified in accordance with the wishes of the Copyright 298 | Holder. 299 | - "Copyright Holder" is whoever is named in the copyright or copyrights for 300 | the package. 301 | - "You" is you, if you're thinking about copying or distributing this Package. 302 | - "Reasonable copying fee" is whatever you can justify on the basis of media 303 | cost, duplication charges, time of people involved, and so on. (You will 304 | not be required to justify it to the Copyright Holder, but only to the 305 | computing community at large as a market that must bear the fee.) 306 | - "Freely Available" means that no fee is charged for the item itself, though 307 | there may be fees involved in handling the item. It also means that 308 | recipients of the item may redistribute it under the same conditions they 309 | received it. 310 | 311 | 1. You may make and give away verbatim copies of the source form of the 312 | Standard Version of this Package without restriction, provided that you 313 | duplicate all of the original copyright notices and associated disclaimers. 314 | 315 | 2. You may apply bug fixes, portability fixes and other modifications derived 316 | from the Public Domain or from the Copyright Holder. A Package modified in such 317 | a way shall still be considered the Standard Version. 318 | 319 | 3. You may otherwise modify your copy of this Package in any way, provided that 320 | you insert a prominent notice in each changed file stating how and when you 321 | changed that file, and provided that you do at least ONE of the following: 322 | 323 | a) place your modifications in the Public Domain or otherwise make them 324 | Freely Available, such as by posting said modifications to Usenet or an 325 | equivalent medium, or placing the modifications on a major archive site 326 | such as ftp.uu.net, or by allowing the Copyright Holder to include your 327 | modifications in the Standard Version of the Package. 328 | 329 | b) use the modified Package only within your corporation or organization. 330 | 331 | c) rename any non-standard executables so the names do not conflict with 332 | standard executables, which must also be provided, and provide a separate 333 | manual page for each non-standard executable that clearly documents how it 334 | differs from the Standard Version. 335 | 336 | d) make other distribution arrangements with the Copyright Holder. 337 | 338 | 4. You may distribute the programs of this Package in object code or executable 339 | form, provided that you do at least ONE of the following: 340 | 341 | a) distribute a Standard Version of the executables and library files, 342 | together with instructions (in the manual page or equivalent) on where to 343 | get the Standard Version. 344 | 345 | b) accompany the distribution with the machine-readable source of the Package 346 | with your modifications. 347 | 348 | c) accompany any non-standard executables with their corresponding Standard 349 | Version executables, giving the non-standard executables non-standard 350 | names, and clearly documenting the differences in manual pages (or 351 | equivalent), together with instructions on where to get the Standard 352 | Version. 353 | 354 | d) make other distribution arrangements with the Copyright Holder. 355 | 356 | 5. You may charge a reasonable copying fee for any distribution of this 357 | Package. You may charge any fee you choose for support of this Package. You 358 | may not charge a fee for this Package itself. However, you may distribute this 359 | Package in aggregate with other (possibly commercial) programs as part of a 360 | larger (possibly commercial) software distribution provided that you do not 361 | advertise this Package as a product of your own. 362 | 363 | 6. The scripts and library files supplied as input to or produced as output 364 | from the programs of this Package do not automatically fall under the copyright 365 | of this Package, but belong to whomever generated them, and may be sold 366 | commercially, and may be aggregated with this Package. 367 | 368 | 7. C or perl subroutines supplied by you and linked into this Package shall not 369 | be considered part of this Package. 370 | 371 | 8. The name of the Copyright Holder may not be used to endorse or promote 372 | products derived from this software without specific prior written permission. 373 | 374 | 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED 375 | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 376 | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 377 | 378 | The End 379 | 380 | -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "abstract" : "PX Pay Interface for www.paymentexpress.com", 3 | "author" : [ 4 | "unknown" 5 | ], 6 | "dynamic_config" : 0, 7 | "generated_by" : "Dist::Zilla version 5.048, Dist::Milla version v1.0.18, CPAN::Meta::Converter version 2.150010", 8 | "license" : [ 9 | "perl_5" 10 | ], 11 | "meta-spec" : { 12 | "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", 13 | "version" : 2 14 | }, 15 | "name" : "Business-PxPay", 16 | "no_index" : { 17 | "directory" : [ 18 | "eg", 19 | "examples", 20 | "inc", 21 | "share", 22 | "t", 23 | "xt" 24 | ] 25 | }, 26 | "prereqs" : { 27 | "configure" : { 28 | "requires" : { 29 | "Module::Build::Tiny" : "0.034" 30 | } 31 | }, 32 | "develop" : { 33 | "requires" : { 34 | "Dist::Milla" : "v1.0.18", 35 | "Test::Pod" : "1.41" 36 | } 37 | }, 38 | "runtime" : { 39 | "requires" : { 40 | "LWP::UserAgent" : "0", 41 | "Net::SSLeay" : "0", 42 | "URI::Escape" : "0", 43 | "XML::Simple" : "0" 44 | } 45 | } 46 | }, 47 | "release_status" : "stable", 48 | "resources" : { 49 | "bugtracker" : { 50 | "web" : "https://github.com/fayland/business-pxpay/issues" 51 | }, 52 | "homepage" : "https://github.com/fayland/business-pxpay", 53 | "repository" : { 54 | "type" : "git", 55 | "url" : "https://github.com/fayland/business-pxpay.git", 56 | "web" : "https://github.com/fayland/business-pxpay" 57 | } 58 | }, 59 | "version" : "0.05", 60 | "x_contributors" : [ 61 | "Fayland Lam ", 62 | "Mohammad S Anwar " 63 | ] 64 | } 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYNOPSIS 2 | 3 | use Business::PxPay; 4 | 5 | my $pxpay = Business::PxPay->new( 6 | userid => 'TestAccount', 7 | key => 'c9fff215b9e2add78d252b78e214880b46a906e73190a380483c1c29acab4157' 8 | ); 9 | 10 | # when submit the cart order 11 | if ( $submit_order ) { 12 | my $rtn = $pxpay->request($args); # $args from CGI params 13 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 14 | print $q->redirect( $rtn->{URI} ); 15 | } else { 16 | die Dumper(\$rtn); 17 | } 18 | } 19 | # when user returns back from pxpal 20 | elsif ( $in_return_or_cancel_page or $params->{result} ) { 21 | my $rtn = $pxpay->result($params->{result}); 22 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 23 | print "Transaction Success!\n"; 24 | } else { 25 | print "Transaction Failed!\n"; 26 | } 27 | } 28 | 29 | # DESCRIPTION 30 | 31 | PX Pay - Payment Express [http://www.paymentexpress.com/](http://www.paymentexpress.com/) 32 | 33 | ## new 34 | 35 | my $pxpay = Business::PxPay->new( 36 | userid => $user, 37 | key => $key 38 | ); 39 | 40 | - `userid` (required) 41 | - `key` (required) 42 | 43 | PxPayUserId & PxPayKey 44 | 45 | - `ua` 46 | - `ua_args` 47 | 48 | By default, we use LWP::UserAgent->new as the UserAgent. you can pass `ua` or `ua_args` to use a different one. 49 | 50 | - `url` 51 | 52 | my $pxpay = Business::PxPay->new( 53 | userid => $user, 54 | key => $key, 55 | url => 'https://sec2.paymentexpress.com/pxpay/pxaccess.aspx', # to test? 56 | ); 57 | 58 | The URL is 'https://www.paymentexpress.com/pxpay/pxaccess.aspx' by default. 59 | 60 | ## Arguments 61 | 62 | All those arguments can be passed into Business::PxPay->new() or pass into $pxpay->request later 63 | 64 | { 65 | TxnType => 'Purchase', 66 | Amount => 10.9, 67 | UrlFail => 'http://test.com', 68 | UrlSuccess => 'http://example.com', 69 | MerchantReference => 'Test Transaction', 70 | EmailAddress => 'test@example.com', 71 | TxnData1 => 'test=A', 72 | TxnData2 => 'data2=B', 73 | TxnData3 => 'data3=C', 74 | }; 75 | 76 | - `Amount` (required) 77 | 78 | Amount value in d.cc format 79 | 80 | - `Currency` (required) 81 | 82 | [http://www.paymentexpress.com/technical\_resources/ecommerce\_hosted/pxpay.html#currencyinput](http://www.paymentexpress.com/technical_resources/ecommerce_hosted/pxpay.html#currencyinput) 83 | 84 | - `UrlFail` (required) 85 | 86 | URL of the merchant transaction failure page. No parameters ("&" or "?") are permitted. 87 | 88 | - `UrlSuccess` (required) 89 | 90 | URL of the merchant transaction success page. No parameters ("&" or "?") are permitted. 91 | 92 | - `TxnType` (required) 93 | 94 | "Auth" or "Purchase" 95 | 96 | - `MerchantReference` (required) 97 | 98 | Reference field to appear on transaction reports 99 | 100 | - `BillingId` 101 | 102 | Optional identifier when adding a card for recurring billing 103 | 104 | - `EmailAddress` 105 | 106 | Optional email address 107 | 108 | - `EnableAddBillCard` 109 | 110 | Required when adding a card to the DPS system for recurring billing. Set element to "1" for true 111 | 112 | - `TxnId` 113 | 114 | A value that uniquely identifies the transaction 115 | 116 | - `TxnData1` 117 | - `TxnData2` 118 | - `TxnData3` 119 | 120 | Optional free text 121 | 122 | - `Opt` 123 | 124 | Optional additional parameter 125 | 126 | ## request 127 | 128 | my $xml = $pxpay->request_xml($args); 129 | my $rtn = $pxpay->request($args); 130 | 131 | request and parse the response XML into HASHREF. sample: 132 | 133 | $VAR1 = \{ 134 | 'URI' => 'https://sec2.paymentexpress.com/pxpay/pxpay.aspx?userid= 135 | TestAccount&request=v51flwn7rvSNcbY86uRMdJ74XB2gHd8ZY-WHqyEYoPm9xd1ROXX00pXYkkuk 136 | dleLlS402E65EjOSCkrqvmAsZUWRCck8RkmIJcRLvG0KZLi7PQRBfpIQ0wzKwdHGKvBCpqhRH6Tx-w93 137 | MRYsP0ThOK4btgTneR_hGEk0supyLeE1taNWCkyFj8KX7rzZ9ncdWRlmciNBsiV4zX4DQ_7Poi9qiblI 138 | 5o0Gm49yb90kUlUtH1hrV3ulzidQbn0CcQKhHFKGX8IVMXiAtVN29r_Cgdzc7dOrwOxY-LBY2h4Or5GQ 139 | hJHB96kjBziu3GyGBvaGfsosNodT3-wyM29A5M-Z62ITkno6JUA6H4', 140 | 'valid' => '1' 141 | }; 142 | 143 | Usually you need redirect to the $rtn->{URI} when valid is 1 144 | 145 | ## result 146 | 147 | my $xml = $pxpay->result_xml($ResponseCode); 148 | my $rtn = $pxpay->result($ResponseCode); 149 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 150 | print "Transaction Success!\n"; 151 | } else { 152 | print "Transaction Failed!\n"; 153 | } 154 | 155 | PxPay will POST to your `UrlSuccess` (or `UrlFail`) when you finish the transaction (or click Cancel button). the POST would contain a param **result** which you can request to get the transaction status. 156 | 157 | ## TIPS 158 | 159 | ### I need params in `UrlSuccess` 160 | 161 | For example, you want your UrlSuccess to be 'http://mysite.com/cgi-bin/cart.cgi?cart\_id=ABC'. 162 | 163 | you need write the request like: 164 | 165 | my $rtn = $pxpay->request( 166 | # others 167 | UrlSuccess => 'http://mysite.com/cgi-bin/cart.cgi', 168 | TxnData1 => 'ABC', 169 | ); 170 | 171 | and you can get the `TxnData1` in 172 | 173 | my $rtn = $pxpay->result($ResponseCode); 174 | my $cart_id = $rtn->{TxnData1} 175 | -------------------------------------------------------------------------------- /cpanfile: -------------------------------------------------------------------------------- 1 | requires 'XML::Simple'; 2 | requires 'LWP::UserAgent'; 3 | requires 'Net::SSLeay'; 4 | requires 'URI::Escape'; -------------------------------------------------------------------------------- /dist.ini: -------------------------------------------------------------------------------- 1 | name = Business-PxPay 2 | 3 | [@Milla] 4 | -------------------------------------------------------------------------------- /lib/Business/PxPay.pm: -------------------------------------------------------------------------------- 1 | package Business::PxPay; 2 | 3 | # ABSTRACT: PX Pay Interface for www.paymentexpress.com 4 | 5 | use warnings; 6 | use strict; 7 | use Carp qw/croak/; 8 | use URI::Escape qw/uri_escape/; 9 | use LWP::UserAgent; 10 | use XML::Simple qw/XMLin XMLout/; 11 | use vars qw/%TRANSACTIONS/; 12 | 13 | our $VERSION = '0.05'; 14 | 15 | %TRANSACTIONS = ( 16 | purchase => 'Purchase', 17 | credit => 'Refund', 18 | authorization => 'Auth', 19 | capture => 'Complete', 20 | validate => 'Validate' 21 | ); 22 | 23 | sub new { 24 | my $class = shift; 25 | my $args = scalar @_ % 2 ? shift : { @_ }; 26 | 27 | # validate 28 | $args->{userid} or croak 'userid is required'; 29 | $args->{key} or croak 'key is required'; 30 | 31 | $args->{url} ||= 'https://sec.paymentexpress.com/pxpay/pxaccess.aspx'; 32 | 33 | unless ( $args->{ua} ) { 34 | my $ua_args = delete $args->{ua_args} || {}; 35 | $args->{ua} = LWP::UserAgent->new(%$ua_args); 36 | } 37 | 38 | bless $args, $class; 39 | } 40 | 41 | sub request { 42 | my $self = shift; 43 | my $args = scalar @_ % 2 ? shift : { @_ }; 44 | 45 | my $xml = $self->request_xml($args); 46 | my $resp = $self->{ua}->post($self->{url}, Content => $xml); 47 | unless ($resp->is_success) { 48 | croak $resp->status_line; 49 | } 50 | my $rtn = XMLin($resp->content, SuppressEmpty => undef); 51 | return $rtn; 52 | } 53 | 54 | sub request_xml { 55 | my $self = shift; 56 | my $args = scalar @_ % 2 ? shift : { @_ }; 57 | 58 | # validate 59 | my $TxnType = $args->{TxnType} || croak 'TxnType is required'; 60 | my $Amount = $args->{Amount} || $self->{Amount} || croak 'Amount is required'; 61 | $Amount = sprintf ("%.2f", $Amount); # .XX format 62 | my $Currency = $args->{Currency} || $self->{Currency} || croak 'Currency is required'; 63 | my $UrlFail = $args->{UrlFail} || $self->{UrlFail} || croak 'UrlFail is required'; 64 | my $UrlSuccess = $args->{UrlSuccess} || $self->{UrlSuccess} || croak 'UrlSuccess is required'; 65 | my $MerchantReference = $args->{MerchantReference} || croak 'MerchantReference is required'; 66 | 67 | # UrlFail can't contain '?' or '&' 68 | if ( $UrlFail =~ /\?/ or $UrlFail =~ /\&/ ) { 69 | croak "UrlFail can't contain '?' or '&', please use TxnData1, TxnData2, TxnData3 or Opt\n"; 70 | } 71 | if ( $UrlSuccess =~ /\?/ or $UrlSuccess =~ /\&/ ) { 72 | croak "UrlSuccess can't contain '?' or '&', please use TxnData1, TxnData2, TxnData3 or Opt\n"; 73 | } 74 | 75 | my $request = { 76 | GenerateRequest => { 77 | PxPayUserId => [ $self->{userid} ], 78 | PxPayKey => [ $self->{key} ], 79 | AmountInput => [ $Amount ], 80 | CurrencyInput => [ $Currency ], 81 | MerchantReference => [ $MerchantReference ], 82 | EmailAddress => [ $args->{EmailAddress} ], 83 | TxnData1 => [ $args->{TxnData1} ], 84 | TxnData2 => [ $args->{TxnData2} ], 85 | TxnData3 => [ $args->{TxnData3} ], 86 | TxnType => [ $TxnType ], 87 | TxnId => [ $args->{TxnId} ], 88 | BillingId => [ $args->{BillingId} ], 89 | EnableAddBillCard => [ $args->{EnableAddBillCard} ], 90 | UrlSuccess => [ $UrlSuccess ], 91 | UrlFail => [ $UrlFail ], 92 | Opt => [ $args->{Opt} ], 93 | }, 94 | }; 95 | return XMLout( $request, KeepRoot => 1 ); 96 | } 97 | 98 | sub result { 99 | my ( $self, $ResponseCode ) = @_; 100 | 101 | my $xml = $self->result_xml($ResponseCode); 102 | my $resp = $self->{ua}->post($self->{url}, Content => $xml); 103 | unless ($resp->is_success) { 104 | croak $resp->status_line; 105 | } 106 | my $rtn = XMLin($resp->content, SuppressEmpty => undef); 107 | return $rtn; 108 | } 109 | 110 | sub result_xml { 111 | my ( $self, $ResponseCode ) = @_; 112 | 113 | my $request = { 114 | ProcessResponse => { 115 | PxPayUserId => [ $self->{userid} ], 116 | PxPayKey => [ $self->{key} ], 117 | Response => [ $ResponseCode ], 118 | }, 119 | }; 120 | return XMLout( $request, KeepRoot => 1 ); 121 | } 122 | 123 | 1; 124 | __END__ 125 | 126 | =head1 SYNOPSIS 127 | 128 | use Business::PxPay; 129 | 130 | my $pxpay = Business::PxPay->new( 131 | userid => 'TestAccount', 132 | key => 'c9fff215b9e2add78d252b78e214880b46a906e73190a380483c1c29acab4157' 133 | ); 134 | 135 | # when submit the cart order 136 | if ( $submit_order ) { 137 | my $rtn = $pxpay->request($args); # $args from CGI params 138 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 139 | print $q->redirect( $rtn->{URI} ); 140 | } else { 141 | die Dumper(\$rtn); 142 | } 143 | } 144 | # when user returns back from pxpal 145 | elsif ( $in_return_or_cancel_page or $params->{result} ) { 146 | my $rtn = $pxpay->result($params->{result}); 147 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 148 | print "Transaction Success!\n"; 149 | } else { 150 | print "Transaction Failed!\n"; 151 | } 152 | } 153 | 154 | =head1 DESCRIPTION 155 | 156 | PX Pay - Payment Express L 157 | 158 | =head2 new 159 | 160 | my $pxpay = Business::PxPay->new( 161 | userid => $user, 162 | key => $key 163 | ); 164 | 165 | =over 4 166 | 167 | =item * C (required) 168 | 169 | =item * C (required) 170 | 171 | PxPayUserId & PxPayKey 172 | 173 | =item * C 174 | 175 | =item * C 176 | 177 | By default, we use LWP::UserAgent->new as the UserAgent. you can pass C or C to use a different one. 178 | 179 | =item * C 180 | 181 | my $pxpay = Business::PxPay->new( 182 | userid => $user, 183 | key => $key, 184 | url => 'https://sec2.paymentexpress.com/pxpay/pxaccess.aspx', # to test? 185 | ); 186 | 187 | The URL is 'https://www.paymentexpress.com/pxpay/pxaccess.aspx' by default. 188 | 189 | =back 190 | 191 | =head2 Arguments 192 | 193 | All those arguments can be passed into Business::PxPay->new() or pass into $pxpay->request later 194 | 195 | { 196 | TxnType => 'Purchase', 197 | Amount => 10.9, 198 | UrlFail => 'http://test.com', 199 | UrlSuccess => 'http://example.com', 200 | MerchantReference => 'Test Transaction', 201 | EmailAddress => 'test@example.com', 202 | TxnData1 => 'test=A', 203 | TxnData2 => 'data2=B', 204 | TxnData3 => 'data3=C', 205 | }; 206 | 207 | =over 4 208 | 209 | =item * C (required) 210 | 211 | Amount value in d.cc format 212 | 213 | =item * C (required) 214 | 215 | L 216 | 217 | =item * C (required) 218 | 219 | URL of the merchant transaction failure page. No parameters ("&" or "?") are permitted. 220 | 221 | =item * C (required) 222 | 223 | URL of the merchant transaction success page. No parameters ("&" or "?") are permitted. 224 | 225 | =item * C (required) 226 | 227 | "Auth" or "Purchase" 228 | 229 | =item * C (required) 230 | 231 | Reference field to appear on transaction reports 232 | 233 | =item * C 234 | 235 | Optional identifier when adding a card for recurring billing 236 | 237 | =item * C 238 | 239 | Optional email address 240 | 241 | =item * C 242 | 243 | Required when adding a card to the DPS system for recurring billing. Set element to "1" for true 244 | 245 | =item * C 246 | 247 | A value that uniquely identifies the transaction 248 | 249 | =item * C 250 | 251 | =item * C 252 | 253 | =item * C 254 | 255 | Optional free text 256 | 257 | =item * C 258 | 259 | Optional additional parameter 260 | 261 | =back 262 | 263 | =head2 request 264 | 265 | my $xml = $pxpay->request_xml($args); 266 | my $rtn = $pxpay->request($args); 267 | 268 | request and parse the response XML into HASHREF. sample: 269 | 270 | $VAR1 = \{ 271 | 'URI' => 'https://sec2.paymentexpress.com/pxpay/pxpay.aspx?userid= 272 | TestAccount&request=v51flwn7rvSNcbY86uRMdJ74XB2gHd8ZY-WHqyEYoPm9xd1ROXX00pXYkkuk 273 | dleLlS402E65EjOSCkrqvmAsZUWRCck8RkmIJcRLvG0KZLi7PQRBfpIQ0wzKwdHGKvBCpqhRH6Tx-w93 274 | MRYsP0ThOK4btgTneR_hGEk0supyLeE1taNWCkyFj8KX7rzZ9ncdWRlmciNBsiV4zX4DQ_7Poi9qiblI 275 | 5o0Gm49yb90kUlUtH1hrV3ulzidQbn0CcQKhHFKGX8IVMXiAtVN29r_Cgdzc7dOrwOxY-LBY2h4Or5GQ 276 | hJHB96kjBziu3GyGBvaGfsosNodT3-wyM29A5M-Z62ITkno6JUA6H4', 277 | 'valid' => '1' 278 | }; 279 | 280 | Usually you need redirect to the $rtn->{URI} when valid is 1 281 | 282 | =head2 result 283 | 284 | my $xml = $pxpay->result_xml($ResponseCode); 285 | my $rtn = $pxpay->result($ResponseCode); 286 | if ( exists $rtn->{valid} and $rtn->{valid} == 1 ) { 287 | print "Transaction Success!\n"; 288 | } else { 289 | print "Transaction Failed!\n"; 290 | } 291 | 292 | PxPay will POST to your C (or C) when you finish the transaction (or click Cancel button). the POST would contain a param B which you can request to get the transaction status. 293 | 294 | =head2 TIPS 295 | 296 | =head3 I need params in C 297 | 298 | For example, you want your UrlSuccess to be 'http://mysite.com/cgi-bin/cart.cgi?cart_id=ABC'. 299 | 300 | you need write the request like: 301 | 302 | my $rtn = $pxpay->request( 303 | # others 304 | UrlSuccess => 'http://mysite.com/cgi-bin/cart.cgi', 305 | TxnData1 => 'ABC', 306 | ); 307 | 308 | and you can get the C in 309 | 310 | my $rtn = $pxpay->result($ResponseCode); 311 | my $cart_id = $rtn->{TxnData1} 312 | -------------------------------------------------------------------------------- /t/00-load.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More tests => 1; 6 | 7 | BEGIN { 8 | use_ok( 'Business::PxPay' ); 9 | } 10 | 11 | diag( "Testing Business::PxPay $Business::PxPay::VERSION, Perl $], $^X" ); 12 | 13 | 1; -------------------------------------------------------------------------------- /t/01-basic.t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | use Data::Dumper; 7 | 8 | BEGIN { 9 | plan skip_all => "ENV{PxPay_USER} and ENV{PxPay_KEY} are required" 10 | unless ( $ENV{PxPay_USER} and $ENV{PxPay_KEY} ); 11 | plan tests => 2; 12 | }; 13 | 14 | use Business::PxPay; 15 | 16 | my $pxpay = Business::PxPay->new( 17 | userid => $ENV{PxPay_USER}, 18 | key => $ENV{PxPay_KEY}, 19 | Currency => 'NZD', 20 | ); 21 | isa_ok($pxpay, 'Business::PxPay'); 22 | 23 | my $data = { 24 | TxnType => 'Purchase', 25 | Amount => 10.9, 26 | UrlFail => 'http://test.com', 27 | UrlSuccess => 'http://example.com', 28 | MerchantReference => 'Test Transaction', 29 | EmailAddress => 'test@example.com', 30 | TxnData1 => 'test=A', 31 | TxnData2 => 'data2=B', 32 | TxnData3 => 'data3=C', 33 | }; 34 | my $out = $pxpay->request_xml( $data ); 35 | #diag($out); 36 | ok( index($out, '10.90') > -1, '10.90' ); 37 | 38 | my $rtn = $pxpay->request($data); 39 | diag(Dumper(\$rtn)); 40 | 41 | 1; -------------------------------------------------------------------------------- /t/pod.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | 7 | # Ensure a recent version of Test::Pod 8 | my $min_tp = 1.22; 9 | eval "use Test::Pod $min_tp"; 10 | plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; 11 | 12 | all_pod_files_ok(); 13 | --------------------------------------------------------------------------------