xieruidong 2 年之前
父節點
當前提交
73be0e366b
共有 78 個文件被更改,包括 4136 次插入13 次删除
  1. 二進制
      application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/libeay32.dll
  2. 二進制
      application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/libssl32.dll
  3. 二進制
      application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/ssleay32.dll
  4. 二進制
      application/common/library/upacp_demo_b2c/assets/对账文件样例/802310048993424_20150905.zip
  5. 二進制
      application/common/library/upacp_demo_b2c/assets/机构接入需做改动/acp_test_sign_inst.pfx
  6. 67 0
      application/common/library/upacp_demo_b2c/assets/机构接入需做改动/机构接入需做改动.txt
  7. 25 0
      application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_enc.cer
  8. 23 0
      application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_middle.cer
  9. 22 0
      application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_root.cer
  10. 二進制
      application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_sign.pfx
  11. 73 0
      application/common/library/upacp_demo_b2c/assets/测试环境配置文件/acp_sdk.ini
  12. 24 0
      application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_enc.cer
  13. 21 0
      application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_middle.cer
  14. 19 0
      application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_root.cer
  15. 69 0
      application/common/library/upacp_demo_b2c/assets/生产环境配置文件/acp_sdk.ini
  16. 64 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/BackReceive.php
  17. 81 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/EncryptCerUpdateQuery.php
  18. 72 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_2_FrontConsume.php
  19. 107 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_3_ConsumeUndo.php
  20. 108 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_4_Refund.php
  21. 105 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_5_Query.php
  22. 189 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_6_FileTransfer.php
  23. 68 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_1_FrontPreauth.php
  24. 105 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_2_PreauthUndo.php
  25. 107 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_3_PreauthFinish.php
  26. 107 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_4_PreauthFinishUndo.php
  27. 64 0
      application/common/library/upacp_demo_b2c/demo/api_01_gateway/FrontReceive.php
  28. 23 0
      application/common/library/upacp_demo_b2c/demo/getdir.php
  29. 88 0
      application/common/library/upacp_demo_b2c/demo/multiCertDemo.php
  30. 96 0
      application/common/library/upacp_demo_b2c/demo/multiKeyDemo.php
  31. 100 0
      application/common/library/upacp_demo_b2c/index_01_gateway.php
  32. 40 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume.php
  33. 10 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume_intro.php
  34. 41 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume_undo.php
  35. 36 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/file_transfer.php
  36. 5 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/introduction.php
  37. 40 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth.php
  38. 38 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_finish.php
  39. 38 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_finish_undo.php
  40. 10 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_intro.php
  41. 38 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_undo.php
  42. 31 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/query.php
  43. 129 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/readme.txt
  44. 39 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/refund.php
  45. 31 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/special_use_preauth.php
  46. 48 0
      application/common/library/upacp_demo_b2c/pages/api_01_gateway/special_use_purchase.php
  47. 17 0
      application/common/library/upacp_demo_b2c/pages/dev_faq.php
  48. 7 0
      application/common/library/upacp_demo_b2c/pages/more_faq.php
  49. 131 0
      application/common/library/upacp_demo_b2c/sdk/SDKConfig.php
  50. 75 0
      application/common/library/upacp_demo_b2c/sdk/acp_sdk.ini
  51. 538 0
      application/common/library/upacp_demo_b2c/sdk/acp_service.php
  52. 411 0
      application/common/library/upacp_demo_b2c/sdk/cert_util.php
  53. 196 0
      application/common/library/upacp_demo_b2c/sdk/common.php
  54. 289 0
      application/common/library/upacp_demo_b2c/sdk/log.class.php
  55. 25 0
      application/common/library/upacp_demo_b2c/static/demo.css
  56. 20 0
      application/common/library/upacp_demo_b2c/static/demo.js
  57. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png
  58. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_diagonals-thick_20_666666_40x40.png
  59. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_flat_10_000000_40x100.png
  60. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_100_f6f6f6_1x400.png
  61. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_100_fdf5ce_1x400.png
  62. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_65_ffffff_1x400.png
  63. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png
  64. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
  65. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
  66. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-icons_222222_256x240.png
  67. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-icons_228ef1_256x240.png
  68. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-icons_ef8c08_256x240.png
  69. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-icons_ffd27a_256x240.png
  70. 二進制
      application/common/library/upacp_demo_b2c/static/images/ui-icons_ffffff_256x240.png
  71. 1 0
      application/common/library/upacp_demo_b2c/static/jquery-1.11.2.min.js
  72. 6 0
      application/common/library/upacp_demo_b2c/static/jquery-ui.min.css
  73. 5 0
      application/common/library/upacp_demo_b2c/static/jquery-ui.min.js
  74. 7 0
      application/common/library/upacp_demo_b2c/static/subpage.js
  75. 2 4
      application/common/library/upacp_demo_qrc/demo/api_16_qrc/Form_3_1_UnifiedOrder.php
  76. 4 2
      application/common/library/upacp_demo_qrc/demo/api_16_qrc/Form_6_2_ApplyQrCode.php
  77. 0 6
      application/common/library/upacp_demo_qrc/index_16_qrc.php
  78. 1 1
      application/common/library/upacp_demo_qrc/sdk/SDKConfig.php

二進制
application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/libeay32.dll


二進制
application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/libssl32.dll


二進制
application/common/library/upacp_demo_b2c/assets/windows开启openssl所需dll文件/ssleay32.dll


二進制
application/common/library/upacp_demo_b2c/assets/对账文件样例/802310048993424_20150905.zip


二進制
application/common/library/upacp_demo_b2c/assets/机构接入需做改动/acp_test_sign_inst.pfx


+ 67 - 0
application/common/library/upacp_demo_b2c/assets/机构接入需做改动/机构接入需做改动.txt

@@ -0,0 +1,67 @@
+签名证书改使用机构证书。
+
+
+
+accessType改1
+(除了批量类交易)加下下面4个字段:
+acqInsCode
+merCatCode
+merName
+merAbbr
+
+其中:
+acqInsCode送自己的机构号
+merId测试环境符合格式随便送,生产由收单自己的业务人员定,代收付产品一定要送业务报备的商户号
+merCatCode测试环境除代收付外的产品送一个真实存在的mcc,生产由收单自己的业务人员定,代收付产品一定要送商户号对应的mcc
+merName测试环境符合格式随便送,生产由收单自己的业务人员定
+merAbbr测试环境符合格式随便送,生产由收单自己的业务人员定
+
+
+批量类交易:
+增加acqInsCode送自己的机构号。merCatCode、merName、merId、merAbbr报文域中不送,merId会在文件里送。
+
+
+
+accNo、customerInfo组装的时候用不加密的方式组装,开发包默认启用了加密的方式,不加密的方式在上下文也有写,只是注释掉了。
+
+对账文件同线下方式获取acomn文件,无联机接口获取
+
+
+
+
+
+==============
+
+机构接入对账文件相关说明
+
+机构接入默认无法使用接口下载对账文件(会respCode=98无文件),请联系分公司用ftp方式获取,测试环境可以由测试支持人员手工发送。 
+使用ACOMN文件对账,ACOMN中会包含这个机构号的所有交易,也会包含线下pos的交易。格式参考联网联合规范第二部分和第三部分(文档请向业务部门索取)。区分交易时建议使用商户号来区分,并且保证这个商户号仅做这个产品。如未生成ACOMN文件,可能为业务没给贵司申请配置生成,请联系业务。如果不是非常需要关心订单号字段,也可使用ACOM、ACOMA文件进行对账,这2个文件也包含了除了订单号之外的关键信息了。
+
+标准做法请使用以下4个字段对账:
+1. 代理机构标识码:为贵司机构号。
+2. 发送机构标识码:间联清算00049992、直联清算00049993。(清算方式为业务配置,请咨询业务)
+3. 系统跟踪号:全渠道查询接口/通知接口中的traceNo。
+4. 交易传输时间:全渠道查询接口/通知接口中的traceTime。
+
+非标准做法但也可使用的方法:
+13. 受卡方标识码:merId。
+COMN3. 订单号:文件最后的保留域字段的前32位,取交易的订单号的前32位。
+
+其他参考信息:
+14. 检索参考号:订单号后12位,退货等后续类交易时填的是原交易的订单号后12位。
+10. 交易类型码:参考联网联合规范第二部分的第3域。请自行根据中文描述对应。
+19. 交易返回码:可无视,对收单来说进对账文件的交易一定是成功交易。
+
+==============
+
+
+
+
+
+
+
+
+
+
+
+

+ 25 - 0
application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_enc.cer

@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEPzCCAyegAwIBAgIFEDl2NhIwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMC
+Q04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhv
+cml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMjAwOTExMDI0MzI2WhcN
+MjUwOTExMDI0MzI2WjBzMQswCQYDVQQGEwJDTjESMBAGA1UEChMJQ0ZDQSBPQ0Ex
+MQ0wCwYDVQQLEwRZQ0NBMRUwEwYDVQQLEwxJbmRpdmlkdWFsLTExKjAoBgNVBAMM
+IVlDQ0FA5rWL6K+V5L2/55SoQDAwMDQwMDAwOlNJR05AMTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBALUwYYpqUXZyDAu0gX5d8XkiUfFxdCan/VyLa6Cz
+KH38cjX0QZIShn/O6Cw2hn2WurP/r3LdopLRzTHI0vIDJpQY/0Y135QHRFZHkAH0
+omRTfAZ/atePnRF7VW766LGhR5n05h1nITDHlzCZYPSumpDPpVcJj4y30+G3A5Ou
+1VVAsuLi48XtGIKwRX6gMXI+P75RwHSmPt5/pHlEPT6wUbmF0HBoF2gRBpYZwiSK
+51Z52XUVEk96reolFFLu/9qyL767/v2izd5YuN9i7oSXNw1gDYcLnAuww6V6BUnK
+Kq4KUG6H3Lz3WyXbEay72f12A5pnHWDjLEOwJ2SG1VVMLN8CAwEAAaOB9DCB8TAf
+BgNVHSMEGDAWgBTPcJ1h6518Lrj3ywJA9wmd/jN0gDBIBgNVHSAEQTA/MD0GCGCB
+HIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMv
+dXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91Y3JsLmNmY2EuY29t
+LmNuL1JTQS9jcmw3NTM3Ni5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSwaOVL
+eW+I7Pm7C8lXu94+MTXAzjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQw
+DQYJKoZIhvcNAQEFBQADggEBADhYan/FCZWzD0BS+KvZivpp498eWRqzXjH2QkBv
+IDYv2+Ntue66WxECMW7i9+RZVjyMeYbFkoxVEcg0cE/mcHOnqd1mTBpeb62NRbWR
+OuquWHxcdIHJ/TjGX8+NwtpAKsn/IvTdEBz+EOOzmXuxNqNxV3Gg7Ay3YavWZzci
+h9GEAQ11WKAjaNqq+XO6dDwBSVEQEkvHqf1DeqCZ9wl58I4MvUmAI7wKfnoonquu
+1wCNMxnkHYS5EAk1Zb0nsprjz771+YZI6ai/I2ehn8hyUR46TYmPMn0WyaXkmEO7
+ig055dazyfvMinsHmKyLa/yJvQMlZIWtsKzaNG4ikdA+ELQ=
+-----END CERTIFICATE-----

+ 23 - 0
application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_middle.cer

@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIIDzjCCAragAwIBAgIKGNDz/H99Hd/CxjANBgkqhkiG9w0BAQUFADBZMQswCQYD
+VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODMwMDMx
+NDMzWhcNMzEwNTExMDMxNDMzWjBYMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
+bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRcwFQYDVQQDEw5D
+RkNBIFRFU1QgT0NBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiL
+J/BrdvHSbXNfLIMTwUg9tDtVjMRGXOl6aZnu9IpxjI5SMUJ4hVwgJnmbTokxs6GF
+IXKsCLSm5H1jHLI22ysc/ltByEybLWj5jjJuC9+Uknbl3/Ls1RBG6MogUCqZckuo
+hKrf5DmlV3C/jVLxGn3pUeanvmqVUi4TKpXxgm5QqKSPF8VtQY4qCpNcQwwZqbMr
+D+IfJtfpGAeVrP+Kg6i1t65seeEnVSaLhqpRUDU0PTblOuUv3OhiKJWA3cYWxUrg
+7U7SIHNJLSEUWmjy4mKty+g7Cnjzt29F9qXFb6oB2mR8yt4GHCilw1Rc5RBXY63H
+eTuOwdtGE3M2p7Q++OECAwEAAaOBmDCBlTAfBgNVHSMEGDAWgBR03sWNCn0QGqpp
+g1tNIc6Gm8xxODAMBgNVHRMEBTADAQH/MDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6
+Ly8yMTAuNzQuNDIuMy90ZXN0cmNhL1JTQS9jcmwxLmNybDALBgNVHQ8EBAMCAQYw
+HQYDVR0OBBYEFM9wnWHrnXwuuPfLAkD3CZ3+M3SAMA0GCSqGSIb3DQEBBQUAA4IB
+AQC0JOazrbkk0XMxMMeBCc3lgBId1RjQLgWUZ7zaUISpPstGIrE5A9aB6Ppq0Sxl
+pt2gkFhPEKUqgOFN1CzCDEbP3n4H0chqK1DOMrgTCD8ID5UW+ECTYNe35rZ+1JiF
+lOPEhFL3pv6XSkiKTfDnjum8+wFwUBGlfoWK1Hcx0P2Hk1jcZZKwGTx1IAkesF83
+pufhxHE2Ur7W4d4tfp+eC7XXcA91pdd+VUrAfkj9eKHcDEYZz66HvHzmt6rtJVBa
+pwrtCi9pW3rcm8c/1jSnEETZIaokai0fD7260h/LkD/GrNCibSWxFj1CqyP9Y5Yv
+cj6aA5LnUcJYeNkrQ3V4XvVc
+-----END CERTIFICATE-----

+ 22 - 0
application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_root.cer

@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIKUhN+zB19hbc65jANBgkqhkiG9w0BAQUFADBZMQswCQYD
+VQQGEwJDTjEwMC4GA1UEChMnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MRgwFgYDVQQDEw9DRkNBIFRFU1QgQ1MgQ0EwHhcNMTIwODI5MDUw
+MTI5WhcNMzIwODI5MDUwMTI5WjBZMQswCQYDVQQGEwJDTjEwMC4GA1UEChMnQ2hp
+bmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRgwFgYDVQQDEw9D
+RkNBIFRFU1QgQ1MgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
+rMJGruH6rOBPFxUI7T1ybydSRRtOM1xvkVjQNX0qmYir8feE6Tb0ctgtKR7a20DI
+YCj9kZ5ANBQqjRcj3Soq9XH3cirqhYHJ723OKyTpS0RPQ0N6vtVt3P5JQ+ztjWHd
+qIbbTOQ6O024TGTiqi6uHgMuz9/OVur81X3a5YVkK7jFeZ9o8cTcvQxD853/1sgZ
+QcmR9aUSw0RXH4XFLTrn7n4QSfWKiNotlD8Ag5gS1pH9ONUb6nGkMn3gh1xfJqjm
+ONMSknPXTGiNpXtqvYi8oIvByVCbUDO59IwPP1r1SYyE3P8Nr7DdQRu0KQSdXLoG
+iugSR3fn+toObVAQmplDAgMBAAGjXTBbMB8GA1UdIwQYMBaAFHTexY0KfRAaqmmD
+W00hzoabzHE4MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBR0
+3sWNCn0QGqppg1tNIc6Gm8xxODANBgkqhkiG9w0BAQUFAAOCAQEAM0eTkM35D4hj
+RlGC63wY0h++wVPUvOrObqAVBbzEEQ7ScBienmeY8Q6lWMUTXM9ALibZklpJPcJv
+3ntht7LL6ztd4wdX7E9RzZCQnRvbL9A/BU3NxWdeSpCg/OyPod5oCKP+6Uc7kApi
+F9OtYNWnt3l2Zp/NiedzEQD8H4qEWQLAq+0dFo5BkfVhb/jPcktndpfPOuH1IMhP
+tVcvo6jpFHw4U/nP2Jv59osIE97KJz/SPt2JAYnZOlIDqWwp9/Afvt0/MDr8y0PK
+Q9c6eqIzBx7a9LpUTUl5u1jS+xSDZ/KF2lXnjwaFp7jICLWEMlBstCoogi7KwH9A
+LpJP7/dj9g==
+-----END CERTIFICATE-----

二進制
application/common/library/upacp_demo_b2c/assets/测试环境证书/acp_test_sign.pfx


+ 73 - 0
application/common/library/upacp_demo_b2c/assets/测试环境配置文件/acp_sdk.ini

@@ -0,0 +1,73 @@
+;;;;;;;;;;;;;;SDK配置文件(证书方式签名);;;;;;;;;;;;;;;;
+; 说明:
+; 1. 使用时请将此文件复制到根文件夹下替换原来的acp_sdk.ini。
+; 2. 具体配置项请根据注释修改。
+; 3. sdk默认读取的配置文件路径为sdk文件夹的acp_sdk.ini文件,如果需修改路径,请自行到sdk/SDKConfig.php中修改。
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[acpsdk]
+;;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址);;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;交易请求地址
+acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do
+acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do
+acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do
+acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do
+acpsdk.fileTransUrl=https://filedownload.test.95516.com/
+acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do
+acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do
+acpsdk.orderTransUrl=https://gateway.test.95516.com/gateway/api/order.do
+
+;以下缴费产品使用,其余产品用不到
+acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do
+acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do
+acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do
+acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do
+acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; 报文版本号,固定5.1.0,请勿改动
+acpsdk.version=5.1.0
+
+; 签名方式,证书方式固定01,请勿改动
+acpsdk.signMethod=01
+
+; 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
+acpsdk.ifValidateCNName=false
+
+; 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
+acpsdk.ifValidateRemoteCert=false
+
+;后台通知地址,填写接收银联后台通知的地址,必须外网能访问
+acpsdk.backUrl=http://222.222.222.222:8080/upacp_demo_qrc/demo/api_10_qrc/BackReceive.php
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境签名证书配置 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 多证书的情况证书路径为代码指定,可不对此块做配置。
+; 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
+; 测试环境证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹。生产环境证书由业务部门邮件发送。
+; windows样例:
+acpsdk.signCert.path=D:/certs/acp_test_sign.pfx
+; linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
+;acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp_test_sign.pfx
+
+; 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
+acpsdk.signCert.pwd=000000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;加密证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
+acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;验签证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 验签中级证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.middleCert.path=D:/certs/acp_test_middle.cer
+; 验签根证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.rootCert.path=D:/certs/acp_test_root.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;日志配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 日志打印路径,linux注意要有写权限
+acpsdk.log.file.path=D:/logs/
+; 日志级别,debug级别会打印密钥,生产请用info或以上级别
+acpsdk.log.level=DEBUG

+ 24 - 0
application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_enc.cer

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwKgAwIBAgIFEgg4VmIwDQYJKoZIhvcNAQEFBQAwITELMAkGA1UEBhMC
+Q04xEjAQBgNVBAoTCUNGQ0EgT0NBMTAeFw0xODExMzAwNzUxNDBaFw0yNDAxMDIw
+OTA3MThaMIGFMQswCQYDVQQGEwJjbjESMBAGA1UEChMJQ0ZDQSBPQ0ExMRYwFAYD
+VQQLEw1Mb2NhbCBSQSBPQ0ExMRQwEgYDVQQLEwtFbnRlcnByaXNlczE0MDIGA1UE
+AxQrMDQxQFoxMjAwMDQwMDAwOlNJR05AMDAwNDAwMDA6U0lHTkAwMDAwMDAwMjCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN3BsX/kyJ2BRh2IW4GyYfFs
+4g5RcIEPhzGfo0IztDeqM8cfwRGqklavYHuZfFG6XPb1N/p1rXQlwyBJ6UQwgnVu
+ACyWa9+Cqf664XNp+vIVx9grqor9lzrJK6jTPrd57AJNuhpFGAW0dRAjfF5ZAdpZ
+56gYiWFgp2zTIXGjXoA0MHqYKBGMMYdFSZ3EkRhsJ0jyJeaBep2VmsFDtODliW0X
+5T+cSgPn1+zzlHwu1svmBYxh3ZpEY3hEwR8KQwja5d5b0kUZ5eCepg9OyB8y+K6P
+5VxCN8YHwVsXFYz1rpEmjGp2qObO2A+vyJaaCdtB3AeppsGLwGCIXQ/t5wyjOqEC
+AwEAAaOB8zCB8DAfBgNVHSMEGDAWgBTR2+mIguXdGo9MqgCMvnzyqxv22TBIBgNV
+HSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2Zj
+YS5jb20uY24vdXMvdXMtMTQuaHRtMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9j
+cmwuY2ZjYS5jb20uY24vUlNBL2NybDE3ODgwLmNybDALBgNVHQ8EBAMCA+gwHQYD
+VR0OBBYEFAIndZ83GnekyNLXDbnxhC6+p4aCMB0GA1UdJQQWMBQGCCsGAQUFBwMC
+BggrBgEFBQcDBDANBgkqhkiG9w0BAQUFAAOCAQEASJTBgXZUnzJ7PVv9Ro4LvVtY
+G/8UOyB7d6TPnWkOGsPghVJujwiSpGmzI3wCCqWbQI23sOBuwkRFCZdK11bc01Wb
+bsapui647RfG0zCAd86ggn5eoe41lZRgIVc1PN/te9JtKcdHkAS9n1PUkD64lPVn
+WEMOcUXukW1emQG9WXauQ8+MVWUtQPW3mmNz2pWsrLk4jk9bppCwkY0lT6KRUXWp
+1xfxXF57wOoNR11wx7WQv1zHJok4oJTrM9lQuVLCwFNr7Pmg0JeEZMF7M7fGaBDi
+ecJB+qLudeVOIpFijW6AQfZaLawlT6eco5/UclK95gnCSct1/BgMOe9UMYPG+w==
+-----END CERTIFICATE-----

+ 21 - 0
application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_middle.cer

@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIFEAAAABkwDQYJKoZIhvcNAQEFBQAwIjELMAkGA1UEBhMC
+Q04xEzARBgNVBAoTCkNGQ0EgQ1MgQ0EwHhcNMTEwNTIwMTc0MTI0WhcNMzEwNTE1
+MTc0MTI0WjAhMQswCQYDVQQGEwJDTjESMBAGA1UEChMJQ0ZDQSBPQ0ExMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApR8eQ7of5iMfk2hlgGC9Z0jcpiFs
+f6ligck4WoLNgEiYg7jWL0jKkcxxlTt79maSEHRWHbdYCIQ0gq/xdIY6EUbIJ4Wd
+J46dTHBOL+OVE93P3Qd422WiDMTkYsH3Mb2BcTKK/1B4jPNCL0eqCDmJrYgBiAo8
+FZqm9zHmDNZHwRF/5NsyoqwuZBbTiU+JVZqrxZRtQY2k74H+umQXBNoxxHlsi0QQ
+itqrhuLczY21Q0IsAAYkAuok1amDdTvNBNeP2c0lKs6N8tOfCDzi6Xz+VxMs7nJj
+6sz5GCR1d1rRQDh59DfmxKlWVzAiSDIdAfBAbICLE0NQNAhYulwUSJS1wQIDAQAB
+o4HAMIG9MB8GA1UdIwQYMBaAFFhpydXdFLMToHE8fAONA+Y9D44BMAwGA1UdEwQF
+MAMBAf8wYAYDVR0fBFkwVzBVoFOgUaRPME0xCzAJBgNVBAYTAkNOMRMwEQYDVQQK
+EwpDRkNBIENTIENBMQwwCgYDVQQLEwNDUkwxDDAKBgNVBAsTA1JTQTENMAsGA1UE
+AxMEY3JsMTALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFNHb6YiC5d0aj0yqAIy+fPKr
+G/bZMA0GCSqGSIb3DQEBBQUAA4IBAQAhsQGgMpueLi4lVn+TmU8MN7sO+T9/fg1S
+KPKedwPZ4arpRC2etLtQ1YC4xK8LdZcQVC3cCJ3MXeBLPJS0fVOtMI10LIhasYyy
+U1Zj3OSwPSBbHXwMiaTdphDMG3ZowZ7x/4OL/QS90+Zp8zfCxt9uPWPKS6QR81oa
+nkrXhPJ13zBMhbP8ZpakhSfMqYG8z9l41ujmI92NahrFivl/qQrIVP6A+8KsS45d
+0MVnkM2ggqDDi42KZ05zkpwpLdGOSfZ+V54GqfhjgtYxkd5I3vAGNad0hWPuIQ59
+H2HILbGHI45vG7803rh5CsyqvaW1KUD4i2sLkgs9vI432PyPJVBi
+-----END CERTIFICATE-----

+ 19 - 0
application/common/library/upacp_demo_b2c/assets/生产环境证书/acp_prod_root.cer

@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHzCCAgegAwIBAgIEGCVShDANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJD
+TjETMBEGA1UEChMKQ0ZDQSBDUyBDQTAeFw0xMTA1MjAxNTI3MDVaFw00MTA1MTIx
+NTI3MDVaMCIxCzAJBgNVBAYTAkNOMRMwEQYDVQQKEwpDRkNBIENTIENBMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAshVScIOG1yHCTl2FSU1XHONBWXcS
+tlJr79ZeOZ8GkH+YFG0U60iaveoYBb4B7gAcc/pprxHEhgVr8uRBjlOAfp9vLrRX
+1dJH00j93T7DXVRchGVjD/4x3zyjKLuNekeiBcA+7ry0m3FCHGSj31Kocw4kfrUc
++BsDz4gIXJtsu617/AO4bvA+a+nBfxhwnIRNItsCLkO6qJfGIzeGMO+IYJ1s4XzL
+XCsrXM4ofUj6jblh5Cqo7ZwFRa0dV5lmgOz8xBYzvn/t+8HoIlwRq7zAbw1I8IpC
+VYcaE4+aPBK47hY9o9q9+JAqKbYQQwjLW4MSv4GNCKCVHQCeHD0QLoxtQwIDAQAB
+o10wWzAfBgNVHSMEGDAWgBRYacnV3RSzE6BxPHwDjQPmPQ+OATAMBgNVHRMEBTAD
+AQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUWGnJ1d0UsxOgcTx8A40D5j0PjgEw
+DQYJKoZIhvcNAQEFBQADggEBAGXTChXGscLtYcWtYF8v9OLdvzEWXclSAbyPI15S
+PYVrTleGMfUWraszz9CUrypuoYiWTnhr8ldOZ5HmR1IYIcs/XFQztTruAyCbAnMQ
+s2il3WqEZ1N5N5AG9PeAg/EYoLxJ9+lHpNa9fLjMK9x9IzDu6/qtkdDN6NuJgqTX
+6gk8RpSl8PSaxxhmyum6t1adm5S7fj2IlbWdjHcRUQEBn5l7/MNaleGh1q7+5fc3
+sLIC+udfA42SLYrDCAQGJ8UK5ec37hKSKQxT1WXJnSgP5hcYd+Jmb3AeXz7PoR7t
+8TsDYnMum7OHLlLlxm+wmZ1ew+SCTlz1nwhPaDqWOIZmSXc=
+-----END CERTIFICATE-----

+ 69 - 0
application/common/library/upacp_demo_b2c/assets/生产环境配置文件/acp_sdk.ini

@@ -0,0 +1,69 @@
+;;;;;;;;;;;;;;SDK配置文件(证书方式签名);;;;;;;;;;;;;;;;
+; 说明:
+; 1. 使用时请将此文件复制到根文件夹下替换原来的acp_sdk.ini。
+; 2. 具体配置项请根据注释修改。
+; 3. sdk默认读取的配置文件路径为sdk文件夹的acp_sdk.ini文件,如果需修改路径,请自行到sdk/SDKConfig.php中修改。
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[acpsdk]
+;;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址);;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;交易请求地址
+acpsdk.frontTransUrl=https://gateway.95516.com/gateway/api/frontTransReq.do
+acpsdk.backTransUrl=https://gateway.95516.com/gateway/api/backTransReq.do
+acpsdk.singleQueryUrl=https://gateway.95516.com/gateway/api/queryTrans.do
+acpsdk.batchTransUrl=https://gateway.95516.com/gateway/api/batchTrans.do
+acpsdk.fileTransUrl=https://filedownload.95516.com/
+acpsdk.appTransUrl=https://gateway.95516.com/gateway/api/appTransReq.do
+acpsdk.cardTransUrl=https://gateway.95516.com/gateway/api/cardTransReq.do
+acpsdk.orderTransUrl=https://gateway.95516.com/gateway/api/order.do
+
+;以下缴费产品使用,其余产品用不到
+acpsdk.jfFrontTransUrl=https://gateway.95516.com/jiaofei/api/frontTransReq.do
+acpsdk.jfBackTransUrl=https://gateway.95516.com/jiaofei/api/backTransReq.do
+acpsdk.jfSingleQueryUrl=https://gateway.95516.com/jiaofei/api/queryTrans.do
+acpsdk.jfCardTransUrl=https://gateway.95516.com/jiaofei/api/cardTransReq.do
+acpsdk.jfAppTransUrl=https://gateway.95516.com/jiaofei/api/appTransReq.do
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; 报文版本号,固定5.1.0,请勿改动
+acpsdk.version=5.1.0
+
+; 签名方式,证书方式固定01,请勿改动
+acpsdk.signMethod=01
+
+; 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
+acpsdk.ifValidateRemoteCert=true
+
+;后台通知地址,填写接收银联后台通知的地址,必须外网能访问
+acpsdk.backUrl=http://222.222.222.222:8080/upacp_demo_qrc/demo/api_10_qrc/BackReceive.php
+
+;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境签名证书配置 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 多证书的情况证书路径为代码指定,可不对此块做配置。
+; 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
+; 测试环境证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹。生产环境证书由业务部门邮件发送。
+; windows样例:
+acpsdk.signCert.path=D:/certs/从cfca获取到的私钥证书.pfx
+; linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
+;acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/从cfca获取到的私钥证书.pfx
+
+; 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
+acpsdk.signCert.pwd=000000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;加密证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
+acpsdk.encryptCert.path=d:/certs/acp_prod_enc.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;验签证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 验签中级证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.middleCert.path=D:/certs/acp_prod_middle.cer
+; 验签根证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.rootCert.path=D:/certs/acp_prod_root.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;日志配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 日志打印路径,linux注意要有写权限
+acpsdk.log.file.path=D:/logs/
+; 日志级别,debug级别会打印密钥,生产请用info或以上级别
+acpsdk.log.level=INFO

+ 64 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/BackReceive.php

@@ -0,0 +1,64 @@
+<?php
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+/**
+ * 交易说明:	前台类交易成功才会发送后台通知。后台类交易(有后台通知的接口)交易结束之后成功失败都会发通知。
+ *              为保证安全,涉及资金类的交易,收到通知后请再发起查询接口确认交易成功。不涉及资金的交易可以以通知接口respCode=00判断成功。
+ *              未收到通知时,查询接口调用时间点请参照此FAQ:https://open.unionpay.com/ajweb/help/faq/list?id=77&level=0&from=0
+ */
+
+$logger = com\unionpay\acp\sdk\LogUtil::getLogger();
+$logger->LogInfo("receive back notify: " . com\unionpay\acp\sdk\createLinkString ( $_POST, false, true ));
+
+?>
+<!DOCTYPE unspecified PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>银联在线交易测试-结果</title>
+<style type="text/css">
+body table tr td {
+	font-size: 14px;
+	word-wrap: break-word;
+	word-break: break-all;
+	empty-cells: show;
+}
+</style>
+</head>
+<body>
+	<table width="800px" border="1" align="center">
+		<tr>
+			<th colspan="2" align="center">银联在线交易测试-交易结果</th>
+		</tr>
+			<?php
+			foreach ( $_POST as $key => $val ) {
+				?>
+			<tr>
+			<td width='30%'><?php echo isset($mpi_arr[$key]) ?$mpi_arr[$key] : $key ;?></td>
+			<td><?php echo $val ;?></td>
+		</tr>
+			<?php }?>
+			<tr>
+			<td width='30%'>验证签名</td>
+			<td><?php			
+			if (isset ( $_POST ['signature'] )) {
+				
+				echo com\unionpay\acp\sdk\AcpService::validate ( $_POST ) ? '验签成功' : '验签失败';
+				$orderId = $_POST ['orderId']; //其他字段也可用类似方式获取
+				$respCode = $_POST ['respCode'];
+                //判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
+
+			} else {
+				echo '签名为空';
+			}
+			?></td>
+		</tr>
+	</table>
+	<?php 
+		//如果卡号我们业务配了会返回且配了需要加密的话,请按此方法解密
+// 		if(array_key_exists ("accNo", $_POST)){
+// 			$accNo = com\unionpay\acp\sdk\AcpService::decryptData($_POST["accNo"]);
+// 			echo  "accNo=" . $accNo . "<br>\n";
+// 		}
+	?>
+</body>
+</html>

+ 81 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/EncryptCerUpdateQuery.php

@@ -0,0 +1,81 @@
+<?php
+use com\unionpay\acp\sdk\AcpService;
+header ( 'Content-type:text/html;charset=utf-8' );
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_wtz/sdk/acp_service.php';
+
+/**
+ * 
+ * 银联加密公钥更新查询(只适用于使用RSA证书加密的方式<即signMethod=01>,其他signMethod=11,12密钥加密用不到此交易)
+ * 商户定期(1天1次)向银联全渠道系统发起获取加密公钥信息交易.
+ * 本交易成功后会自动替换配置文件acp_sdk.properties文件中acpsdk.encryptCert.path指定的文件,可用不用手工替换
+ */
+$params = array(
+
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,//版本号
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,//签名方法
+		'encoding' => 'utf-8',		           //编码方式
+		'txnType' => '95',		               //交易类型
+		'txnSubType' => '00',		           //交易子类
+		'bizType' => '000000',		           //业务类型
+		'accessType' => '0',		           //接入类型
+		'channelType' => '07',		           //渠道类型
+		'certType' => '01',		               //01:敏感信息加密公钥(只有01可用)
+		
+		//TODO 以下信息需要填写
+		'merId' => "777290058110048",		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+		'orderId' => date('YmdHis'),	//商户订单号,如上送短信验证码,请填写获取验证码时一样的orderId,此处默认取demo演示页面传递的参数
+		'txnTime' => date('YmdHis'),	//订单发送时间,如上送短信验证码,请填写获取验证码时一样的txnTime,此处默认取demo演示页面传递的参数
+);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url );
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+    echo "交易成功。<br>\n";
+    $resultCode = AcpService::updateEncryptCert($result_arr);
+    if ($resultCode === 1){
+    	echo "加密公钥更新成功。<br>\n";
+    } else if ($resultCode === 0){
+    	echo "加密公钥无更新。<br>\n";
+    } else {
+    	echo "加密公钥更新失败。<br>\n";
+    }
+}else {
+    //其他应答码做以失败处理
+     //TODO
+     echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}

+ 72 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_2_FrontConsume.php

@@ -0,0 +1,72 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:消费:前台跳转,有前台通知应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 提示:该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》,<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ *              《全渠道平台接入接口规范 第3部分 文件接口》(对账文件格式说明)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易确定交易成功,前台通知不能作为判断成功的标准.
+ *       2)交易状态查询交易(Form_6_5_Query)建议调用机制:前台类交易建议间隔(5分、10分、30分、60分、120分)发起交易查询,如果查询到结果成功,则不用再查询。(失败,处理中,查询不到订单均可能为中间状态)。也可以建议商户使用payTimeout(支付超时时间),过了这个时间点查询,得到的结果为最终结果。
+ */
+
+$params = array(
+		
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,                 //版本号
+		'encoding' => 'utf-8',				  //编码方式
+		'txnType' => '01',				      //交易类型
+		'txnSubType' => '01',				  //交易子类
+		'bizType' => '000201',				  //业务类型
+		'frontUrl' =>  com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontUrl,  //前台通知地址
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl,	  //后台通知地址
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,	              //签名方法
+		'channelType' => '08',	              //渠道类型,07-PC,08-手机
+		'accessType' => '0',		          //接入类型
+		'currencyCode' => '156',	          //交易币种,境内商户固定156
+		
+		//TODO 以下信息需要填写
+		'merId' => $_POST["merId"],		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+		'orderId' => $_POST["orderId"],	//商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
+		'txnTime' => $_POST["txnTime"],	//订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],	//交易金额,单位分,此处默认取demo演示页面传递的参数
+		
+		// 订单超时时间。
+		// 超过此时间后,除网银交易外,其他交易银联系统会拒绝受理,提示超时。 跳转银行网银交易如果超时后交易成功,会自动退款,大约5个工作日金额返还到持卡人账户。
+		// 此时间建议取支付时的北京时间加15分钟。
+		// 超过超时时间调查询接口应答origRespCode不是A6或者00的就可以判断为失败。
+		'payTimeout' => date('YmdHis', strtotime('+15 minutes')), 
+
+		'riskRateInfo' =>'{commodityName=测试商品名称}',
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+		
+		//TODO 其他特殊用法请查看 special_use_purchase.php
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params );
+$uri = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontTransUrl;
+$html_form = com\unionpay\acp\sdk\AcpService::createAutoFormHtml( $params, $uri );
+echo $html_form;

+ 107 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_3_ConsumeUndo.php

@@ -0,0 +1,107 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:消费撤销类交易:后台消费撤销交易,有同步应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易确定交易成功
+ *       2)消费撤销仅能对当清算日的消费做,必须为全额,一般当日或第二日到账。
+ */
+ 
+
+$params = array(
+		
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		      //版本号
+		'encoding' => 'utf-8',		      //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		      //签名方法
+		'txnType' => '31',		          //交易类型	
+		'txnSubType' => '00',		      //交易子类
+		'bizType' => '000201',		      //业务类型
+		'accessType' => '0',		      //接入类型
+		'channelType' => '07',		      //渠道类型
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址	
+		
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	    //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],			//商户代码,请改成自己的测试商户号,此处默认取demo演示页面传递的参数
+		'origQryId' => $_POST["origQryId"], //原消费的queryId,可以从查询接口或者通知接口中获取,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原消费,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],       //交易金额,消费撤销时需和原消费一致,此处默认取demo演示页面传递的参数
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	echo "POST请求失败:" . $errMsg;
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+    //交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
+    //TODO
+    echo "受理成功。<br>\n";
+} else if ($result_arr["respCode"] == "03"
+ 	    || $result_arr["respCode"] == "04"
+ 	    || $result_arr["respCode"] == "05" ){
+    //后续需发起交易状态查询交易确定交易状态
+    //TODO
+     echo "处理超时,请稍微查询。<br>\n";
+} else {
+    //其他应答码做以失败处理
+     //TODO
+     echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}

+ 108 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_4_Refund.php

@@ -0,0 +1,108 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+ include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:退货交易:后台资金类交易,有同步应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+ 
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明: 1)以后台通知或交易状态查询交易(Form_6_5_Query)确定交易成功,建议发起查询交易的机制:可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)
+ *        2)退货金额不超过总金额,可以进行多次退货
+ *        3)退货能对11个月内的消费做(包括当清算日),支持部分退货或全额退货,到账时间较长,一般1-10个清算日(多数发卡行5天内,但工行可能会10天),所有银行都支持
+ */
+ 
+
+$params = array(
+
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		      //版本号
+		'encoding' => 'utf-8',		      //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		      //签名方法
+		'txnType' => '04',		          //交易类型
+		'txnSubType' => '00',		      //交易子类
+		'bizType' => '000201',		      //业务类型
+		'accessType' => '0',		      //接入类型
+		'channelType' => '07',		      //渠道类型
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址
+		
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	    //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],	        //商户代码,请改成自己的测试商户号,此处默认取demo演示页面传递的参数
+		'origQryId' => $_POST["origQryId"], //原消费的queryId,可以从查询接口或者通知接口中获取,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原消费,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],       //交易金额,退货总金额需要小于等于原消费
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+    //交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
+    //TODO
+    echo "受理成功。<br>\n";
+} else if ($result_arr["respCode"] == "03"
+ 	    || $result_arr["respCode"] == "04"
+ 	    || $result_arr["respCode"] == "05" ){
+    //后续需发起交易状态查询交易确定交易状态
+    //TODO
+     echo "处理超时,请稍微查询。<br>\n";
+} else {
+    //其他应答码做以失败处理
+     //TODO
+     echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}

+ 105 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_5_Query.php

@@ -0,0 +1,105 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+ include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:交易状态查询交易:只有同步应答 <br>
+ * 日期: 2015-09<br>
+ 
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能及规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》,<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                           2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明: 1)对前台交易发起交易状态查询:前台类交易建议间隔(5分、10分、30分、60分、120分)发起交易查询,如果查询到结果成功,则不用再查询。(失败,处理中,查询不到订单均可能为中间状态)。也可以建议商户使用payTimeout(支付超时时间),过了这个时间点查询,得到的结果为最终结果。
+ *        2)对后台交易发起交易状态查询:后台类资金类交易同步返回00,成功银联有后台通知,商户也可以发起 查询交易,可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)。
+ *        					         后台类资金类同步返03 04 05响应码及未得到银联响应(读超时)需发起查询交易,可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)。
+ */
+
+$params = array(
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		  //版本号
+		'encoding' => 'utf-8',		  //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		  //签名方法
+		'txnType' => '00',		      //交易类型
+		'txnSubType' => '00',		  //交易子类
+		'bizType' => '000000',		  //业务类型
+		'accessType' => '0',		  //接入类型
+		'channelType' => '07',		  //渠道类型
+
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	//请修改被查询的交易的订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],	    //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	//请修改被查询的交易的订单发送时间,格式为YYYYMMDDhhmmss,此处默认取demo演示页面传递的参数
+);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->singleQueryUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+	if ($result_arr["origRespCode"] == "00"){
+		//交易成功
+		//TODO
+		echo "交易成功。<br>\n";
+	} else if ($result_arr["origRespCode"] == "03"
+			|| $result_arr["origRespCode"] == "04"
+			|| $result_arr["origRespCode"] == "05"){
+		//后续需发起交易状态查询交易确定交易状态
+		//TODO
+		echo "交易处理中,请稍微查询。<br>\n";
+	} else {
+		//其他应答码做以失败处理
+		//TODO
+		echo "交易失败:" . $result_arr["origRespMsg"] . "。<br>\n";
+	}
+} else if ($result_arr["respCode"] == "03"
+		|| $result_arr["respCode"] == "04"
+		|| $result_arr["respCode"] == "05" ){
+	//后续需发起交易状态查询交易确定交易状态
+	//TODO
+	echo "处理超时,请稍微查询。<br>\n";
+} else {
+	//其他应答码做以失败处理
+	//TODO
+	echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+
+

+ 189 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_6_FileTransfer.php

@@ -0,0 +1,189 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+$projName = getProjName();
+include_once $_SERVER ['DOCUMENT_ROOT'] . "/$projName/sdk/acp_service.php";
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ *
+ * 产品:跳转网关支付产品<br>
+ * 交易:文件传输类接口:后台获取对账文件交易,只有同步应答 <br>
+ * 日期: 2015-09<br>
+
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载 产品接口规范 《网关支付产品接口规范》<br>
+ * 《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 《全渠道平台接入接口规范 第3部分 文件接口》(对账文件格式说明)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ * 测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ * 2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明: 对账文件的格式请参考《全渠道平台接入接口规范 第3部分 文件接口》
+ * 对账文件示例见目录file下的802310048993424_20150905.zip
+ * 解析落地后的对账文件可以参考BaseDemo.java中的parseZMFile();parseZMEFile();方法
+ */
+
+
+$params = array (
+
+		// 以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,//版本号
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,//签名方法
+		'encoding' => 'utf-8',		           //编码方式
+		'txnType' => '76', // 交易类型
+		'txnSubType' => '01', // 交易子类
+		'bizType' => '000000', // 业务类型
+		'accessType' => '0', // 接入类型
+		'fileType' => '00', // 文件类型
+
+		// TODO 以下信息需要填写
+		'txnTime' => $_POST ["txnTime"], // 订单发送时间,取北京时间,格式为YYYYMMDDhhmmss,此处默认取demo演示页面传递的参数
+		'merId' => $_POST ["merId"], // 商户代码,请替换实际商户号测试,如使用的是自助化平台注册的商户号(777开头的),该商户号没有权限测文件下载接口的,请使用测试参数里写的文件下载的商户号和日期测,如需真实交易文件,请使用自助化平台下载文件,此处默认取demo演示页面传递的参数
+		'settleDate' => $_POST ["settleDate"]
+) // 清算日期,格式为MMDD,此处默认取demo演示页面传递的参数
+;
+
+com\unionpay\acp\sdk\AcpService::sign ( $params );
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->fileTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url );
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "98"){
+	//文件不存在
+	//TODO
+	echo "文件不存在。<br>\n";
+	return;
+} else if ($result_arr["respCode"] != "00") {
+	//其他应答码做以失败处理
+	//TODO
+	echo "失败:respCode=" . $result_arr["respCode"] . "。<br>\n";
+	return;
+}
+
+echo "返回成功。<br>\n";
+
+$filePath = "d:/file/";
+//TODO 处理文件,保存路径上面那行设置,注意预先建立文件夹并授读写权限
+if ( com\unionpay\acp\sdk\AcpService::deCodeFileContent( $result_arr,  $filePath) == false) {
+	echo '文件保存失败,请查看日志提示的错误信息<br\n>';
+	return;
+}
+
+echo '文件已成功保存到' . $filePath. "目录下<br\n>";
+
+//=================================================================
+//TODO 下面是调用的方法是分析对账文件的样例代码,请按照自己的需要修改并集成到自己的代码中
+analyze_file($filePath, $result_arr ["fileName"]);
+
+function analyze_file($filePath, $fileName){
+	//解压
+	$zip = new ZipArchive ();
+	if ($zip->open ( $filePath . "/" . $fileName ) === TRUE) {
+		$zip->extractTo ( $filePath );
+		$zip->close ();
+
+		//遍历解压之后目录下的所有文件,对流水文件分析
+		foreach (scandir($filePath) as $fileName) {
+			$list = null;
+			if (substr($fileName, 0, 3) == "INN" && substr($fileName, 11, 3) == "ZM_")
+				$list = parse_file_zm ( $filePath."/".$fileName ); //处理流水文件
+			else if (substr($fileName, 0, 3) == "INN" && substr($fileName, 11, 4) == "ZME_")
+				$list = parse_file_zme ( $filePath."/".$fileName ); //处理差错流水文件
+				
+			if ($list != null) {
+				echo ($fileName . "部分参数读取(读取方式请参考Form_6_6_FileTransfer的代码):<br>\n");
+				echo ("<table border='1'>\n");
+				echo ("<tr><th>txnType</th><th>orderId</th><th>txnTime(MMDDhhmmss)</th></tr>");
+				foreach ($list as $dic) {
+					//TODO 参看https://open.unionpay.com/ajweb/help?id=258,根据编号获取即可,例如订单号12、交易类型20。
+					//具体写代码时可能边读文件边修改数据库性能会更好,请注意自行根据parseFile中的读取方法修改。
+					echo("<tr>\n");
+					echo("<td>" . $dic[20] . "</td>\n");//txnType
+					echo("<td>" . $dic[12] . "</td>\n");//orderId
+					echo("<td>" . $dic[5] . "</td>\n");//txnTime不带年份
+					echo("</tr>\n");
+				}
+				echo ("</table>\n");
+			}
+		}
+	} else {
+		echo '解压失败';
+	}
+}
+
+//全渠道商户一般交易明细流水文件
+function parse_file_zm($filePath){
+	$lengthArray = array(3, 11, 11, 6, 10, 19, 12, 4, 2, 21, 2, 32, 2, 6, 10, 13, 13, 4, 15, 2, 2, 6, 2, 4, 32, 1, 21, 15, 1, 15, 32, 13, 13, 8, 32, 13, 13, 12, 2, 1, 32, 98 );
+	return parse_file($filePath, $lengthArray);
+}
+
+//全渠道商户差错交易明细流水文件
+function parse_file_zme($filePath){
+	$lengthArray = array(3, 11, 11, 6, 10, 19, 12, 4, 2, 2, 6, 10, 4, 12, 13, 13, 15, 15, 1, 12, 2, 135);
+	return parse_file($filePath, $lengthArray);
+}
+
+function parse_file($filePath, $lengthArray) {
+	if (! file_exists ( $filePath ))
+		return false;
+
+	// 解析的结果MAP,key为对账文件列序号,value为解析的值
+	$dataList = array ();
+	$s = "";
+	foreach ( file ( $filePath ) as $s ) {
+		$dataMap = array ();
+		$leftIndex = 0;
+		$rightIndex = 0;
+		for($i = 0; $i < count ( $lengthArray ); $i ++) {
+			$rightIndex = $leftIndex + $lengthArray [$i];
+			$filed = substr ( $s, $leftIndex, $lengthArray [$i] );
+			$filed = iconv("GBK", "UTF-8", $filed);
+			$leftIndex = $rightIndex + 1;
+			$dataMap [$i + 1] = $filed;
+		}
+		$dataList [] = $dataMap;
+	}
+	return $dataList;
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+
+function getProjName(){
+	$dir = str_replace("\\","/", dirname(__FILE__));
+	$rootDir = str_replace("\\", "/", $_SERVER ['DOCUMENT_ROOT']);
+	if($rootDir[strlen($rootDir) - 1] != "/") $rootDir = $rootDir . "/";
+	$index = strlen($rootDir);
+	$dir = substr($dir, $index);
+	$index = strpos($dir, "/");
+	$projName = substr($dir, 0, $index);
+	return $projName;
+}

+ 68 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_1_FrontPreauth.php

@@ -0,0 +1,68 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:预授权:前台跳转,有前台通知应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 提示:该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》,<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ *              《全渠道平台接入接口规范 第3部分 文件接口》(对账文件格式说明)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易确定交易成功,前台通知不能作为判断成功的标准.
+ *       2)交易状态查询交易(Form_6_5_Query)建议调用机制:前台类交易间隔(5分、10分、30分、60分、120分)发起交易查询,如果查询到结果成功,则不用再查询。(失败,处理中,查询不到订单均可能为中间状态)。也可以建议商户使用payTimeout(支付超时时间),过了这个时间点查询,得到的结果为最终结果。
+ */
+
+$params = array(
+		
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,                 //版本号
+		'encoding' => 'utf-8',				  //编码方式
+		'txnType' => '02',				      //交易类型
+		'txnSubType' => '01',				  //交易子类
+		'bizType' => '000201',				  //业务类型
+		'frontUrl' =>  com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontUrl,  //前台通知地址
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl,	  //后台通知地址
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,	              //签名方法
+		'channelType' => '08',	              //渠道类型,07-PC,08-手机
+		'accessType' => '0',		          //接入类型
+		'currencyCode' => '156',	          //交易币种,境内商户固定156
+		
+		//TODO 以下信息需要填写
+		'merId' => $_POST["merId"],		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+		'orderId' => $_POST["orderId"],	//商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
+		'txnTime' => $_POST["txnTime"],	//订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],	//交易金额,单位分,此处默认取demo演示页面传递的参数
+		
+		'payTimeout' => date('YmdHis', strtotime('+15 minutes')), //订单超时时间。超过超时时间调查询接口应答origRespCode不是A6或者00的就可以判断为失败。
+
+		'riskRateInfo' =>'{commodityName=测试商品名称}',
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+		
+		//TODO 其他特殊用法请查看 special_use_preauth.php
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params );
+$uri = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontTransUrl;
+$html_form = com\unionpay\acp\sdk\AcpService::createAutoFormHtml( $params, $uri );
+echo $html_form;

+ 105 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_2_PreauthUndo.php

@@ -0,0 +1,105 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+ include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:预授权撤销:后台交易,有同步应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+ 
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易(Form_6_5_Query)确定交易成功。建议发起查询交易的机制:可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)
+ *       2)预授权撤销对清算日30天之内(包括第30天)的预授权做,必须为预授权金额全额撤销。
+ */
+ 
+$params = array(
+
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		      //版本号
+		'encoding' => 'utf-8',		      //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		      //签名方法
+		'txnType' => '32',		          //交易类型
+		'txnSubType' => '00',		      //交易子类
+		'bizType' => '000201',		      //业务类型
+		'accessType' => '0',		      //接入类型
+		'channelType' => '07',		      //渠道类型
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址
+		
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	    //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原预授权,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],	        //商户代码,请改成自己的测试商户号,此处默认取demo演示页面传递的参数
+		'origQryId' => $_POST["origQryId"], //原预授权的queryId,可以从预授权的查询接口或者通知接口中获取,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原预授权,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],       //交易金额,需要等于原预授权
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+	);
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+	//交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
+	//TODO
+	echo "受理成功。<br>\n";
+} else if ($result_arr["respCode"] == "03"
+		|| $result_arr["respCode"] == "04"
+		|| $result_arr["respCode"] == "05" ){
+	//后续需发起交易状态查询交易确定交易状态
+	//TODO
+	echo "处理超时,请稍微查询。<br>\n";
+} else {
+	//其他应答码做以失败处理
+	//TODO
+	echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}

+ 107 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_3_PreauthFinish.php

@@ -0,0 +1,107 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+ include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:预授权完成:后台交易,有同步应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+ 
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易(Form_6_5_Query)确定交易成功。建议发起查询交易的机制:可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)
+ *       2)预授权完成交易必须在预授权交易30日内发起,否则预授权交易自动解冻。预授权完成金额可以是预授权金额的(0-115%](大于0小于等于115)
+ */
+
+$params = array(
+
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		      //版本号
+		'encoding' => 'utf-8',		      //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		      //签名方法
+		'txnType' => '03',		          //交易类型
+		'txnSubType' => '00',		      //交易子类
+		'bizType' => '000201',		      //业务类型
+		'accessType' => '0',		      //接入类型
+		'channelType' => '07',		      //渠道类型
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址
+		
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	    //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原交易,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],	        //商户代码,请改成自己的测试商户号,此处默认取demo演示页面传递的参数
+		'origQryId' => $_POST["origQryId"], //原预授权的queryId,可以从预授权的查询接口或者通知接口中获取,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原交易,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],       //交易金额,范围为预授权金额的0-115%
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+    //交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
+    //TODO
+    echo "受理成功。<br>\n";
+} else if ($result_arr["respCode"] == "03"
+ 	    || $result_arr["respCode"] == "04"
+ 	    || $result_arr["respCode"] == "05" ){
+    //后续需发起交易状态查询交易确定交易状态
+    //TODO
+     echo "处理超时,请稍微查询。<br>\n";
+} else {
+    //其他应答码做以失败处理
+     //TODO
+     echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+

+ 107 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/Form_6_7_4_PreauthFinishUndo.php

@@ -0,0 +1,107 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+ include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+
+/**
+ * 重要:联调测试时请仔细阅读注释!
+ * 
+ * 产品:跳转网关支付产品<br>
+ * 交易:预授权完成撤销:后台交易,有同步应答和后台通知应答<br>
+ * 日期: 2015-09<br>
+ 
+ * 版权: 中国银联<br>
+ * 说明:以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己需要,按照技术文档编写。该代码仅供参考,不提供编码性能规范性等方面的保障<br>
+ * 该接口参考文档位置:open.unionpay.com帮助中心 下载  产品接口规范  《网关支付产品接口规范》<br>
+ *              《平台接入接口规范-第5部分-附录》(内包含应答码接口规范,全渠道平台银行名称-简码对照表)<br>
+ * 测试过程中的如果遇到疑问或问题您可以:1)优先在open平台中查找答案:
+ * 							        调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+ *                             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+ *                          2) 咨询在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持。
+ * 交易说明:1)以后台通知或交易状态查询交易(Form_6_5_Query)确定交易成功。建议发起查询交易的机制:可查询N次(不超过6次),每次时间间隔2N秒发起,即间隔1,2,4,8,16,32S查询(查询到03,04,05继续查询,否则终止查询)
+ *       2)预授权完成撤销交易仅能对当清算日的预授权做,必须为预授权完成金额全额撤销。
+ */
+
+$params = array(
+
+		//以下信息非特殊情况不需要改动
+		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,		      //版本号
+		'encoding' => 'utf-8',		      //编码方式
+		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,		      //签名方法
+		'txnType' => '33',		          //交易类型
+		'txnSubType' => '00',		      //交易子类
+		'bizType' => '000201',		      //业务类型
+		'accessType' => '0',		      //接入类型
+		'channelType' => '07',		      //渠道类型
+		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址
+		
+		//TODO 以下信息需要填写
+		'orderId' => $_POST["orderId"],	    //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原交易,此处默认取demo演示页面传递的参数
+		'merId' => $_POST["merId"],	        //商户代码,请改成自己的测试商户号,此处默认取demo演示页面传递的参数
+		'origQryId' => $_POST["origQryId"], //原预授权完成的queryId,可以从预授权完成的查询接口或者通知接口中获取,此处默认取demo演示页面传递的参数
+		'txnTime' => $_POST["txnTime"],	    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原交易,此处默认取demo演示页面传递的参数
+		'txnAmt' => $_POST["txnAmt"],       //交易金额,同原预授权完成的金额
+
+		// 请求方保留域,
+		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
+		// 出现部分特殊字符时可能影响解析,请按下面建议的方式填写:
+		// 1. 如果能确定内容不会出现&={}[]"'等符号时,可以直接填写数据,建议的方法如下。
+		//    'reqReserved' =>'透传信息1|透传信息2|透传信息3',
+		// 2. 内容可能出现&={}[]"'符号时:
+		// 1) 如果需要对账文件里能显示,可将字符替换成全角&={}【】“‘字符(自己写代码,此处不演示);
+		// 2) 如果对账文件没有显示要求,可做一下base64(如下)。
+		//    注意控制数据长度,实际传输的数据长度不能超过1024位。
+		//    查询、通知等接口解析时使用base64_decode解base64后再对数据做后续解析。
+		//    'reqReserved' => base64_encode('任意格式的信息都可以'),
+	);
+
+com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, "" );
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validate ($result_arr) ){
+	echo "应答报文验签失败<br>\n";
+	return;
+}
+
+echo "应答报文验签成功<br>\n";
+if ($result_arr["respCode"] == "00"){
+    //交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
+    //TODO
+    echo "受理成功。<br>\n";
+} else if ($result_arr["respCode"] == "03"
+ 	    || $result_arr["respCode"] == "04"
+ 	    || $result_arr["respCode"] == "05" ){
+    //后续需发起交易状态查询交易确定交易状态
+    //TODO
+     echo "处理超时,请稍微查询。<br>\n";
+} else {
+    //其他应答码做以失败处理
+     //TODO
+     echo "失败:" . $result_arr["respMsg"] . "。<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+

+ 64 - 0
application/common/library/upacp_demo_b2c/demo/api_01_gateway/FrontReceive.php

@@ -0,0 +1,64 @@
+<?php
+include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/sdk/acp_service.php';
+/**
+ * 交易说明:	前台类交易成功才会发送后台通知。后台类交易(有后台通知的接口)交易结束之后成功失败都会发通知。
+ *              为保证安全,涉及资金类的交易,收到通知后请再发起查询接口确认交易成功。不涉及资金的交易可以以通知接口respCode=00判断成功。
+ *              未收到通知时,查询接口调用时间点请参照此FAQ:https://open.unionpay.com/ajweb/help/faq/list?id=77&level=0&from=0
+ */
+
+$logger = com\unionpay\acp\sdk\LogUtil::getLogger();
+$logger->LogInfo("receive front notify: " . com\unionpay\acp\sdk\createLinkString ( $_POST, false, true ));
+
+?>
+<!DOCTYPE unspecified PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>银联在线交易测试-结果</title>
+<style type="text/css">
+body table tr td {
+	font-size: 14px;
+	word-wrap: break-word;
+	word-break: break-all;
+	empty-cells: show;
+}
+</style>
+</head>
+<body>
+	<table width="800px" border="1" align="center">
+		<tr>
+			<th colspan="2" align="center">银联在线交易测试-交易结果</th>
+		</tr>
+			<?php
+			foreach ( $_POST as $key => $val ) {
+				?>
+			<tr>
+			<td width='30%'><?php echo isset($mpi_arr[$key]) ?$mpi_arr[$key] : $key ;?></td>
+			<td><?php echo $val ;?></td>
+		</tr>
+			<?php }?>
+			<tr>
+			<td width='30%'>验证签名</td>
+			<td><?php			
+			if (isset ( $_POST ['signature'] )) {
+				
+				echo com\unionpay\acp\sdk\AcpService::validate ( $_POST ) ? '验签成功' : '验签失败';
+				$orderId = $_POST ['orderId']; //其他字段也可用类似方式获取
+				$respCode = $_POST ['respCode'];
+                //判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
+
+			} else {
+				echo '签名为空';
+			}
+			?></td>
+		</tr>
+	</table>
+	<?php 
+		//如果卡号我们业务配了会返回且配了需要加密的话,请按此方法解密
+// 		if(array_key_exists ("accNo", $_POST)){
+// 			$accNo = com\unionpay\acp\sdk\AcpService::decryptData($_POST["accNo"]);
+// 			echo  "accNo=" . $accNo . "<br>\n";
+// 		}
+	?>
+</body>
+</html>

+ 23 - 0
application/common/library/upacp_demo_b2c/demo/getdir.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * 用于获取服务器绝对路径。
+ * 将此文件放在服务器上,然后访问一下。
+ * 比如获取到:
+ * /Users/xxxx/Sites/upacp_demo_app/demo/getdir.php
+ * 比如证书放在工程upacp_demo_app的certs文件夹下,
+ * 则配置文件的绝对路径需要配置为/Users/xxxx/Sites/upacp_demo_app/cert/acp_test_sign.pfx
+ * 其他路径配置也类似。
+ */
+// function getDir()
+//  {
+//  	$a = debug_backtrace();
+//  	echo $a[0]["file"];
+//  }
+ function getDir()
+ {
+ 	$dir = str_replace("\\","/", __FILE__);
+ 	echo $dir;
+ }
+ 
+getDir();
+

+ 88 - 0
application/common/library/upacp_demo_b2c/demo/multiCertDemo.php

@@ -0,0 +1,88 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+$projName = getProjName();
+include_once $_SERVER ['DOCUMENT_ROOT'] . "/$projName/sdk/acp_service.php";
+
+/**
+ * 多证书demo
+ * 【【【尽量和业务部门申请使用证书共享,尽量不要用多证书。】】】
+ * 
+ */
+ 
+$params = array(
+		
+		'version' => '5.1.0',		  //版本号
+		'encoding' => 'utf-8',		  //编码方式
+		'signMethod' => '01',		  //签名方法
+		'txnType' => '00',		      //交易类型	
+		'txnSubType' => '00',		  //交易子类
+		'bizType' => '000000',		  //业务类型
+		'accessType' => '0',		  //接入类型
+		'channelType' => '07',		  //渠道类型
+		'orderId' => date('YmdHis'),  //订单号,演示用
+		'merId' => '777290058110048', //商户代码,演示用
+		'txnTime' => date('YmdHis'),  //订单发送时间,演示用
+		
+	);
+
+$cert_path = 'D:\certs\testMultiCert.pfx';
+$cert_pwd = '123456';
+com\unionpay\acp\sdk\AcpService::signByCertInfo( $params, $cert_path, $cert_pwd ); // 签名
+//此地址为示例这里要替换成做具体交易的地址(具体交易地址请查看对应示例中用到的地址)
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->singleQueryUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, array() );
+	echo "POST请求失败,具体报错请看下日志。<br>\n" ;
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+
+$cert_path = 'D:\certs\testMultiCert2.pfx';
+$cert_pwd = '000000';
+com\unionpay\acp\sdk\AcpService::signByCertInfo ( $params, $cert_path, $cert_pwd ); // 签名
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, array() );
+	echo "POST请求失败,具体报错请看下日志。<br>\n" ;
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+
+function getProjName(){
+	$dir = str_replace("\\","/", dirname(__FILE__));
+	$rootDir = str_replace("\\", "/", $_SERVER ['DOCUMENT_ROOT']);
+	if($rootDir[strlen($rootDir) - 1] != "/") $rootDir = $rootDir . "/";
+	$index = strlen($rootDir);
+	$dir = substr($dir, $index);
+	$index = strpos($dir, "/");
+	$projName = substr($dir, 0, $index);
+	return $projName;
+}
+

+ 96 - 0
application/common/library/upacp_demo_b2c/demo/multiKeyDemo.php

@@ -0,0 +1,96 @@
+<?php
+header ( 'Content-type:text/html;charset=utf-8' );
+$projName = getProjName();
+include_once $_SERVER ['DOCUMENT_ROOT'] . "/$projName/sdk/acp_service.php";
+
+/**
+ * 多证书demo
+ * 【【【尽量和业务部门申请使用证书共享,尽量不要用多证书。】】】
+ * 
+ */
+ 
+$params = array(
+		
+		'version' => '5.1.0',		  //版本号
+		'encoding' => 'utf-8',		  //编码方式
+		'signMethod' => '11',		  //签名方法
+		'txnType' => '00',		      //交易类型	
+		'txnSubType' => '00',		  //交易子类
+		'bizType' => '000000',		  //业务类型
+		'accessType' => '0',		  //接入类型
+		'channelType' => '07',		  //渠道类型
+		'orderId' => date('YmdHis'),  //订单号,演示用
+		'merId' => '777290058110048', //商户代码,演示用
+		'txnTime' => date('YmdHis'),  //订单发送时间,演示用
+		
+	);
+
+com\unionpay\acp\sdk\AcpService::signBySecureKey( $params, "88888888" ); // 签名
+//此地址为示例这里要替换成做具体交易的地址(具体交易地址请查看对应示例中用到的地址)
+$url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->singleQueryUrl;
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, array() );
+	echo "POST请求失败,具体报错请看下日志。<br>\n" ;
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validateBySecureKey ($result_arr, "88888888") ){
+	echo "应答报文验签失败<br>\n";
+} else {
+	echo "应答报文验签成功<br>\n";
+}
+
+
+com\unionpay\acp\sdk\AcpService::signBySecureKey ( $params, "12345678" ); // 签名
+
+$result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+
+if(count($result_arr)<=0) { //没收到200应答的情况
+	printResult ( $url, $params, array() );
+	echo "POST请求失败,具体报错请看下日志。<br>\n" ;
+	return;
+}
+
+printResult ($url, $params, $result_arr ); //页面打印请求应答数据
+
+if (!com\unionpay\acp\sdk\AcpService::validateBySecureKey ($result_arr, "12345678") ){
+	echo "应答报文验签失败<br>\n";
+} else {
+	echo "应答报文验签成功<br>\n";
+}
+
+/**
+ * 打印请求应答
+ *
+ * @param
+ *        	$url
+ * @param
+ *        	$req
+ * @param
+ *        	$resp
+ */
+function printResult($url, $req, $resp) {
+	echo "=============<br>\n";
+	echo "地址:" . $url . "<br>\n";
+	echo "请求:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $req, false, true ) ) ) . "<br>\n";
+	echo "应答:" . str_replace ( "\n", "\n<br>", htmlentities ( com\unionpay\acp\sdk\createLinkString ( $resp , false, false )) ) . "<br>\n";
+	echo "=============<br>\n";
+}
+
+
+function getProjName(){
+	$dir = str_replace("\\","/", dirname(__FILE__));
+	$rootDir = str_replace("\\", "/", $_SERVER ['DOCUMENT_ROOT']);
+	if($rootDir[strlen($rootDir) - 1] != "/") $rootDir = $rootDir . "/";
+	$index = strlen($rootDir);
+	$dir = substr($dir, $index);
+	$index = strpos($dir, "/");
+	$projName = substr($dir, 0, $index);
+	return $projName;
+}
+

+ 100 - 0
application/common/library/upacp_demo_b2c/index_01_gateway.php

@@ -0,0 +1,100 @@
+<!doctype html>
+<html lang="en">
+
+<!-- 
+
+  借地写说明:
+  jquery-ui的说明参考:http://www.runoob.com/jqueryui/jqueryui-tutorial.html
+  jquery的说明参考:http://www.w3school.com.cn/jquery/index.asp
+  
+  tabs-api为横向的标签,下面定义的div比如tabs-purchase是竖向的标签,按已有的往下添加,名字别重复就行。
+  
+  新增横向标签:
+  1. <div id="tabs-api"><ul><li>下面新加个a标签,指向一个锚点。
+  2. 上一条的<ul>同级别下新加一个<div>,id使用上一条锚点指定的id。
+  
+  新增纵向标签:
+  1. js加一行,设置纵向标签的参数。
+  2. 总之参考已有的样例吧。
+  
+-->
+
+<head>
+  <meta charset="utf-8">
+  <title>网关产品示例</title>
+  <link rel="stylesheet" href="static/jquery-ui.min.css">
+  <script src="static/jquery-1.11.2.min.js"></script>
+  <script src="static/jquery-ui.min.js"></script>
+  <script src="static/demo.js"></script>
+  <script>
+  	$(function() {
+	    setApiDemoTabs("#tabs-purchase");
+	    setApiDemoTabs("#tabs-preauth");
+	  });
+  </script>
+  <link rel="stylesheet" href="static/demo.css">
+
+</head>
+<body style="background-color:#e5eecc;">
+<div id="wrapper">
+
+<div id="header">
+<h2>网关产品示例</h2>
+
+</div>
+
+<div id="tabs-api">
+  <ul>
+    <li><a href="#tabs-api-1">前言</a></li>
+    <li><a href="#tabs-api-2">消费样例</a></li>
+    <li><a href="#tabs-api-3">预授权样例</a></li>
+    <li><a href="#tabs-api-4">常见开发问题</a></li>
+  </ul>
+  
+  <div id="tabs-api-1">
+    <?php include 'pages/api_01_gateway/introduction.php';?>
+  </div>
+  
+  <div id="tabs-api-4">
+    <?php include 'pages/dev_faq.php';?>
+  </div>
+  
+  <div id="tabs-api-2">
+	<div id="tabs-purchase">
+	  <ul>
+	    <li><a href="#tabs-purchase-1">说明</a></li>
+	    <li><a href="pages/api_01_gateway/consume.php">跳转网关页面支付</a></li>
+	    <li><a href="pages/api_01_gateway/query.php">交易状态查询</a></li>
+			<li><a href="pages/api_01_gateway/consume_undo.php">消费撤销</a></li>
+			<li><a href="pages/api_01_gateway/refund.php">退货</a></li>
+			<li><a href="pages/api_01_gateway/file_transfer.php">对账文件下载</a></li>
+	  </ul>
+	  <div id="tabs-purchase-1">
+	     <?php include 'pages/api_01_gateway/consume_intro.php';?>
+	  </div>
+	</div>
+  </div>
+  
+  <div id="tabs-api-3">
+	  <div id="tabs-preauth">
+		  <ul>
+		    <li><a href="#tabs-preauth-1">说明</a></li>
+		    <li><a href="pages/api_01_gateway/preauth.php">跳转网关页面预授权</a></li>
+		    <li><a href="pages/api_01_gateway/query.php">交易状态查询</a></li>
+		    <li><a href="pages/api_01_gateway/preauth_finish.php">预授权完成</a></li>
+		    <li><a href="pages/api_01_gateway/preauth_undo.php">预授权撤销</a></li>
+		    <li><a href="pages/api_01_gateway/preauth_finish_undo.php">预授权完成撤销</a></li>
+		    <li><a href="pages/api_01_gateway/refund.php">退货</a></li>
+		    <li><a href="pages/api_01_gateway/file_transfer.php">对账文件下载</a></li>
+		  </ul>
+		  <div id="tabs-preauth-1">
+	        <?php include 'pages/api_01_gateway/preauth_intro.php';?>
+	      </div>
+		</div>
+	  </div> <!-- end of tabs-api-3-->
+  </div> <!-- end of tabs-api-->
+</div><!-- end of wrapper-->
+ 
+ 
+</body>
+</html>

+ 40 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume.php

@@ -0,0 +1,40 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_2_FrontConsume.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="1000" title="单位为分 " required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间,YYYYMMDDhhmmss格式" value="<?php echo date('YmdHis')?>" title="取北京时间" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="跳转银联页面支付" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>跳转网关页面您可能会遇到...</h4>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=4&level=0&from=0" target="_blank">测试卡信息</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=24&level=0&from=0" target="_blank">http400错误</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=9100004" target="_blank">测试环境9100004</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=40&level=0&from=0" target="_blank">正式环境9100004</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=113&level=0&from=0" target="_blank">打开页面出现"此网站的安全证书有问题"或"您的连接不是私密连接"等阻止打开支付页面跳转的内容</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=34&level=0&from=0" target="_blank">测试环境跳转报http501错误</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=169&level=0&from=0" target="_blank">wap跳转银联后白屏</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=5131008" target="_blank">5131008</a><br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 10 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume_intro.php

@@ -0,0 +1,10 @@
+测试卡号:与银联测试环境联调使用的卡号 <a href="https://open.unionpay.com/ajweb/help/faq/list?id=4&level=0&from=0" target="_blank">测试卡号</a><br><br>
+<a href="pages/api_01_gateway/special_use_purchase.php" target="_blank">报文特殊用法</a><br>
+<br>
+常见咨询:<br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=9&level=0&from=0" target="_blank">消费撤销和退货有什么区别?</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=120&level=0&from=0" target="_blank">退款类交易的手续费如何收取?</a><br>
+<br>
+【重要提醒】<br>
+请注意退货和消费撤销是异步接口,同步应答respCode=00仅代表受理成功,需用查询接口的origRespCode和通知接口的respCode判断。<br>
+<br>

+ 41 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/consume_undo.php

@@ -0,0 +1,41 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_3_ConsumeUndo.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="" title="单位分,需与原消费一致" required="required"/>
+</p>
+<p>
+<label>原交易流水号:</label>
+<input id="origQryId" type="text" name="origQryId" placeholder="原交易流水号" value="" title="原交易流水号,从查询或通知接口中获取 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>消费撤销您可能会遇到...</h4>
+<p class="faq">
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2010002" target="_blank">2010002</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2040004" target="_blank">2040004</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2040006" target="_blank">2040006</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2050001" target="_blank">2050001</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2050002" target="_blank">2050002</a><br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 36 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/file_transfer.php

@@ -0,0 +1,36 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_6_FileTransfer.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="700000000000001" title="请替换实际商户号测试,自助化平台注册的商户号(777开头的)无法测试此接口,如无真实商户号,请使用700000000000001测试此接口" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>清算日期:</label>
+<input id="settleDate" type="text" name="settleDate" placeholder="清算日期" value="0119" title="格式为MMDD" required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>对账文件下载您可能会遇到...</h4>
+
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=94&level=0&from=0" target="_blank">http500错误</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=95&level=0&from=0" target="_blank">respcode=99、98</a><br>
+<br>
+另外请注意阅读:<br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=119&level=0&from=0" target="_blank">对账文件什么时候能下载?</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=70&level=0&from=0" target="_blank">清算日期settleDate是什么?</a><br>
+<br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 5 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/introduction.php

@@ -0,0 +1,5 @@
+<!-- <h3>内容标题 1</h3> -->
+<p>联调集成前请仔细阅读:<a href="pages/api_01_gateway/readme.txt" target="_blank">readme.txt</a></p>
+<p>接口规范(请求报文,同步应答,异步应答报文字段)参考:<a href="https://open.unionpay.com/ajweb/help/file" target="_blank">产品接口规范->《网关支付产品接口规范》</a></p>
+<p>应答码规范(同步应答,异步应答中respCode的值)参考:<a href="https://open.unionpay.com/ajweb/help/file" target="_blank">产品接口规范->《平台接入接口规范-第5部分-附录》</a></p>
+<p>对账文件格式参考:<a href="https://open.unionpay.com/ajweb/help/file" target="_blank">产品接口规范->《全渠道平台接入接口规范 第3部分 文件接口》</a></p>

+ 40 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth.php

@@ -0,0 +1,40 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_7_1_FrontPreauth.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="1000" title="单位为分 " required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间,YYYYMMDDhhmmss格式" value="<?php echo date('YmdHis')?>" title="取北京时间" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="跳转银联页面预授权" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>跳转网关页面您可能会遇到...</h4>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=4&level=0&from=0" target="_blank">测试卡信息</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=24&level=0&from=0" target="_blank">http400错误</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=9100004" target="_blank">测试环境9100004</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=40&level=0&from=0" target="_blank">正式环境9100004</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=113&level=0&from=0" target="_blank">打开页面出现"此网站的安全证书有问题"或"您的连接不是私密连接"等阻止打开支付页面跳转的内容</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=34&level=0&from=0" target="_blank">测试环境跳转报http501错误</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=169&level=0&from=0" target="_blank">wap跳转银联后白屏</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=5131008" target="_blank">5131008</a><br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 38 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_finish.php

@@ -0,0 +1,38 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_7_3_PreauthFinish.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="" title="单位分,小于等于原预授权的115%" required="required"/>
+</p>
+<p>
+<label>原交易流水号:</label>
+<input id="origQryId" type="text" name="origQryId" placeholder="原交易流水号" value="" title="原交易流水号,从原预授权的查询或通知接口中获取 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>预授权完成您可能会遇到...</h4>
+<p class="faq">
+测试的人不多,木有足量样本/(ㄒoㄒ)/~~<br>
+<br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 38 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_finish_undo.php

@@ -0,0 +1,38 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_7_4_PreauthFinishUndo.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="" title="单位分,需与原预授权完成的金额一致" required="required"/>
+</p>
+<p>
+<label>原交易流水号:</label>
+<input id="origQryId" type="text" name="origQryId" placeholder="原交易流水号" value="" title="原交易流水号,从原预授权完成的查询或通知接口中获取 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>预授权完成撤销您可能会遇到...</h4>
+<p class="faq">
+测试的人不多,木有足量样本/(ㄒoㄒ)/~~<br>
+<br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 10 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_intro.php

@@ -0,0 +1,10 @@
+测试卡号:与银联测试环境联调使用的卡号 <a href="https://open.unionpay.com/ajweb/help/faq/list?id=4&level=0&from=0" target="_blank">测试卡号</a><br><br>
+<a href="pages/api_01_gateway/special_use_preauth.php" target="_blank">报文特殊用法</a><br>
+<br>
+常见咨询:<br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=120&level=0&from=0" target="_blank">退款类交易的手续费如何收取?</a><br>
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=189&level=0&from=0" target="_blank">预授权完成撤销后能否再次预授权完成?</a><br>
+<br>
+【重要提醒】<br>
+请注意预授权撤销、预授权完成、预授权完成撤销均为异步接口,同步应答respCode=00仅代表受理成功,需用查询接口的origRespCode和通知接口的respCode判断。<br>
+<br>

+ 38 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/preauth_undo.php

@@ -0,0 +1,38 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_7_2_PreauthUndo.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="" title="单位分,需与原预授权一致" required="required"/>
+</p>
+<p>
+<label>原交易流水号:</label>
+<input id="origQryId" type="text" name="origQryId" placeholder="原交易流水号" value="" title="原交易流水号,从原预授权的查询或通知接口中获取 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>预授权撤销您可能会遇到...</h4>
+<p class="faq">
+测试的人不多,木有足量样本/(ㄒoㄒ)/~~<br>
+<br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 31 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/query.php

@@ -0,0 +1,31 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_5_Query.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="填写被查询交易的订单发送时间" value="" title="填写被查询交易的订单发送时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="填写被查询交易的商户订单号" value="" title="填写被查询交易的商户订单号" required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?"  />
+</p>
+</form>
+
+<div class="question" >
+<hr />
+<h4>交易状态查询您可能会遇到...</h4>
+<p class="faq">
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2600000" target="_blank">=查无此交易[2600000]</a><br>
+ <br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>
+

+ 129 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/readme.txt

@@ -0,0 +1,129 @@
+─────────────────────────────────────────     
+产品名称:  跳转网关支付产品
+修改日期:  2016-08-09
+─────────────────────────────────────────
+
+───────────
+ **重要**
+1) 联调前请仔细阅读以下说明。
+2) 本示例PHP版本基于5.3,需开启curl、openssl功能。
+3) 此工程可以跑起来测试,建议使用chrome、firefox打开。
+  全渠道PC网关/WAP支付产品消费交易示例地址为:http://IP:端口/upacp_demo_b2c/index_01_gateway.php
+───────────
+
+───────────
+示例工程目录结构
+───────────
+
+upacp_demo_b2c
+  │
+  ├assets ┈┈┈┈┈┈┈┈┈相关资源目录
+  │  │  
+  │  ├windows开启openssl所需dll文件┈┈┈┈┈windows环境php开启openssl功能所需dll文件
+  │  │
+  │  ├机构接入需做改动┈┈┈┈┈┈┈┈┈收单机构接入需要做的改动
+  │  │      
+  │  ├测试环境证书
+  │  │  │  
+  │  │  ├acp_test_enc.cer┈┈┈┈┈┈┈┈┈ 【重要】测试环境敏感信息加密证书(所有商户固定使用同一个) 
+  │  │  │  
+  │  │  ├acp_test_sign.pfx ┈┈┈┈┈┈┈┈┈ 【重要】 测试环境签名私钥证书(所有商户固定使用同一个) 
+  │  │  │  
+  │  │  ├acp_test_root.cer ┈┈┈┈┈┈┈┈┈ 【重要】 测试环境验签公钥证书根证书  (所有商户固定使用同一个) 
+  │  │  │  
+  │  │  └acp_test_middle.cer ┈┈┈┈┈┈┈┈┈【重要】 测试环境验签公钥证书中级证书  (所有商户固定使用同一个)  
+  │  │  
+  │  ├生产环境证书
+  │  │  │
+  │  │  ├acp_prod_enc.cer┈┈┈┈┈┈┈┈┈【重要】 生产环境敏感信息加密证书(所有商户固定使用同一个)
+  │  │  │
+  │  │  ├acp_prod_root.cer ┈┈┈┈┈┈┈┈┈【重要】 生产环境验签公钥根证书  (所有商户固定使用同一个)  
+  │  │  │
+  │  │  └acp_prod_middle.cer ┈┈┈┈┈┈┈┈┈【重要】 生产环境验签公钥中级证书  (所有商户固定使用同一个)  
+  │  │  
+  │  ├生产环境配置文件
+  │  │  │
+  │  │  └acp_sdk.ini ┈┈┈┈┈┈┈┈┈ 【重要】 生产环境配置文件样例
+  │  │ 
+  │  ├测试环境配置文件
+  │  │  │
+  │  │  └acp_sdk.ini ┈┈┈┈┈┈┈┈┈ 【重要】 测试环境配置文件样例
+  │  │ 
+  │  └对账文件样例 
+  │     │
+  │     └802310048993424_20150905.zip┈┈┈┈┈┈┈┈┈提供的对账文件样例(如果需要可以参考)
+  │  
+  ├demo ┈┈┈┈┈┈┈┈┈ 示例代码
+  │  │  
+  │  ├api_01_gateway ┈┈┈┈┈┈┈┈┈ 网关产品
+  │  │  │  
+  │  │  ├BackReceive.php┈┈┈┈┈后台通知处理示例类 
+  │  │  │  
+  │  │  ├FrontReceive.php┈┈┈┈┈前台通知处理示例类   
+  │  │  │    
+  │  │  ├EncryptCerUpdateQuery.php ┈┈┈┈┈加密证书更新示例类(后台)         
+  │  │  │  
+  │  │  ├Form_6_2_FrontConsume.php┈┈┈┈┈前台跳转银联支付页面示例类(前台)
+  │  │  │  
+  │  │  ├Form_6_3_ConsumeUndo.php┈┈┈┈┈消费撤销交易示例类 (后台)
+  │  │  │  
+  │  │  ├Form_6_4_Refund.php┈┈┈┈┈退货交易示例类 (后台)
+  │  │  │  
+  │  │  ├Form_6_5_Query.php┈┈┈┈┈交易状态查询示例类 (后台)
+  │  │  │  
+  │  │  ├Form_6_6_FileTransfer.php┈┈┈┈┈对账文件下载示例类 (后台)  
+  │  │  │  
+  │  │  ├Form_6_7_1_FrontPreauth.php┈┈┈┈┈前台跳转银联预授权页面示例类(前台)
+  │  │  │  
+  │  │  ├Form_6_7_2_PreauthUndo.php┈┈┈┈┈预授权撤销交易示例类 (后台)
+  │  │  │  
+  │  │  ├Form_6_7_3_PreauthFinish.php┈┈┈┈┈预授权完成交易示例类 (后台)
+  │  │  │  
+  │  │  └Form_6_7_4_PreauthFinishUndo.php┈┈┈┈┈预授权完成撤销交易示例类 (后台)
+  │  │   
+  │  ├getdir.php ┈┈┈┈┈获取服务器绝对路径
+  │  │   
+  │  ├multiCertDemo.php ┈┈┈┈┈多证书demo(证书方式)
+  │  │   
+  │  └multiKeyDemo.php ┈┈┈┈┈多证书demo(秘钥方式)
+  │  
+  ├sdk┈┈┈┈┈┈sdk,除了acp_service外的类为内部使用,不用看,acp_sdk.ini为配置文件
+  │  │
+  │  ├acp_sdk.ini ┈┈┈┈ 配置文件,默认取了“assets/测试环境配置文件”文件夹下的证书方式签名配置文件。
+  │  │
+  │  └acp_service.php ┈┈┈┈┈┈ 全渠道 SDK API类
+  │
+  ├pages ┈┈┈┈┈┈┈┈┈ demo演示相关页面,内容不重要,未列举
+  │
+  ├static ┈┈┈┈ demo演示相关js和css,内容不重要,未列举
+  │
+  └index_01_gateway.php ┈┈┈┈demo演示入口页面
+
+───────────
+**注意**
+
+1.【接口规范】该接口参考文档位置:
+      接口产品规范:open.unionpay.com帮助中心 下载  产品接口规范  《网关产品接口规范》
+      应答码规范:《平台接入接口规范-第5部分-附录》
+
+2.【关于商户号】开发包中使用的商户号777290058110097是open.unionpay.com注册的测试商户号,只能在入网测试环境使用;
+      可以先使用这个商户调通交易(当然您也可以自己在这个网站注册一个777开头的测试商户号,自己注册后要开通权限:https://open.unionpay.com 登陆后 右上角我的测试-我的产品-将未测试的产品点击成测试状态,过10分钟后就有权限了)
+      正式线上环境请替换成申请的正式商户号,并确保商户号有对应的权限,如果报了无此交易权限等错误,请联系您申请接入银联的业务人员确认您做的交易是否开通了对应的权限。
+  
+3.【关于证书文件】测试环境使用的签名私钥证书,验签公钥证书均在assets目录下找得到,使用的时候只需要配置到sdk/acp_sdk.ini指定的目录下即可,使用我们的demo不需要了解签名,验签等算法,详细参考配置文件注释。
+                                      生产环境使用的验签公钥证书,生产环境的acp_sdk.ini文件在assets提供了,只需要配置上私钥和公钥即可,详细参考配置文件注释。
+
+4.测试过程中的如果遇到疑问或问题您可以:
+  1)优先在open平台中查找答案:
+  	 调试过程中的问题或其他问题请在 https://open.unionpay.com/ajweb/help/faq/list 帮助中心 FAQ 搜索解决方案
+             测试过程中产生的7位应答码问题疑问请在https://open.unionpay.com/ajweb/help/respCode/respCodeList 输入应答码搜索解决方案
+  2)咨询【测试环境】在线人工支持: open.unionpay.com注册一个用户并登陆在右上角点击“在线客服”,咨询人工QQ测试支持,咨询的时候需把 请求报文,请求银联地址,报错描述 贴给支持人员以方便查问题。
+  3)测试环境测试支付请使用测试卡号测试, FAQ搜索“测试卡”。
+  4)切换生产环境要点请FAQ搜索“切换”。
+  
+5.【生产环境问题】连接银联生产环境测试遇到的问题 如果通过open平台无法解决 请登陆merchant.unionpay.com 菜单"服务单管理"->"创建服务单"请求排查问题。
+
+6. 为方便查看代码没正确执行的原因,测试时请务必打开php.ini的display_errors,正式使用时再设置Off。
+
+───────────
+

+ 39 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/refund.php

@@ -0,0 +1,39 @@
+<form class="api-form" method="post" action="demo/api_01_gateway/Form_6_4_Refund.php" target="_blank">
+<p>
+<label>商户号:</label>
+<input id="merId" type="text" name="merId" placeholder="" value="777290058110048" title="默认商户号仅作为联调测试使用,正式上线还请使用正式申请的商户号" required="required"/>
+</p>
+<p>
+<label>订单发送时间:</label>
+<input id="txnTime" type="text" name="txnTime" placeholder="订单发送时间" value="<?php echo date('YmdHis')?>" title="取北京时间,YYYYMMDDhhmmss格式" required="required"/>
+</p>
+<p>
+<label>商户订单号:</label>
+<input id="orderId" type="text" name="orderId" placeholder="商户订单号" value="<?php echo date('YmdHis')?>" title="自行定义,8-32位数字字母" required="required"/>
+</p>
+<p>
+<label>交易金额:</label>
+<input id="txnAmt" type="text" name="txnAmt" placeholder="交易金额" value="" title="单位分,退货总金额要小于等于原消费" required="required"/>
+</p>
+<p>
+<label>原交易流水号:</label>
+<input id="origQryId" type="text" name="origQryId" placeholder="原交易流水号" value="" title="原交易流水号,从查询或通知接口中获取 " required="required"/>
+</p>
+<p>
+<label>&nbsp;</label>
+<input type="submit" class="button" value="提交" />
+<input type="button" class="showFaqBtn" value="遇到问题?" />
+</p>
+</form>
+
+<div class="question">
+<hr />
+<h4>退货接口您可能会遇到...</h4>
+<p class="faq">
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2010002" target="_blank">2010002</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2040004" target="_blank">2040004</a><br>
+<a href="https://open.unionpay.com//ajweb/help/respCode/respCodeList?respCode=2050004" target="_blank">2050004</a><br>
+</p>
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+</div>

+ 31 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/special_use_preauth.php

@@ -0,0 +1,31 @@
+<h4>----------请求报文-------------------</h4>
+
+<h4>1. 支付商户直接上送卡号并在银联页面锁定该卡号支付:</h4>
+<p class="faq">
+  【适用PC端网页】<br>
+  需上送accNo,reserved这个2个字段(仅送accNo时会默认填上这个卡号,但用户仍能修改卡,必须送保留域用法防止修改)<br>
+  'accNo' => '6221558812340000',  //需锁定的卡号<br>
+  'reserved' => '{cardNumberLock=1}',    //银联定义的系统保留域,锁定卡号,值不能修改<br>
+  【使用wap支付】<br>
+   上送accNo即可,持卡人不能修改卡号<br>
+</p>
+
+<h4>2. 网关支付成功后,自动跳转到商户网站:</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+联系银联业务运营部门开通商户号的自动跳转功能。<br>
+</p>
+
+<h4>3. 透传字段</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+  'reqReserved' =>'透传信息', //请求方保留域,透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自 己希望透传的数据<br>
+</p>
+
+<h4>-------------通知报文---------------------</h4>
+<h4>6. 返回报文中返回卡号,卡类型,支付方式:</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+需在申请入网或者已经入网后给银联业务运营中心申请开通这3种权限<br>
+
+</p>

+ 48 - 0
application/common/library/upacp_demo_b2c/pages/api_01_gateway/special_use_purchase.php

@@ -0,0 +1,48 @@
+<h4>----------请求报文-------------------</h4>
+<h4>1. PC端商户界面点击银行网银图标直接跳转到银行网银支付</h4>
+<p class="faq">
+【仅适用PC端网页支付】<br>
+(因测试环境所有商户号都默认不允许开通网银支付权限,所以要实现此功能需要使用正式申请的商户号去生产环境测试):<br>
+  1)联系银联业务运营部门开通商户号的网银前置权限<br>
+  2)上送issInsCode字段,该字段的值参考《平台接入接口规范-第5部分-附录》(全渠道平台银行名称-简码对照表)<br>
+  'issInsCode' => 'WGTEST',  //发卡机构代码,此处默认值为测试环境仿真的机构简码<br>
+</p>
+
+<h4>2. 支付商户直接上送卡号并在银联页面锁定该卡号支付:</h4>
+<p class="faq">
+  【适用PC端网页】<br>
+  需上送accNo,reserved这个2个字段(仅送accNo时会默认填上这个卡号,但用户仍能修改卡,必须送保留域用法防止修改)<br>
+  'accNo' => '6221558812340000',  //需锁定的卡号<br>
+  'reserved' => '{cardNumberLock=1}',    //银联定义的系统保留域,锁定卡号,值不能修改<br>
+  【使用wap支付】<br>
+   上送accNo即可,持卡人不能修改卡号<br>
+</p>
+
+<h4>3. 网关消费支付分期付款实现:</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+  1)联系银联业务运营部门申请开通商户号的分期付款权限<br>
+  2)请求报文txnSubType送03<br>
+  <span style="width:2em;"></span>'txnSubType' => '03',                //分期付款<br>
+  3)测试环境使用测试卡号6221558812340000做金额介于10-1000之间金额的消费交易测试<br>
+</p>
+
+<h4>4. 网关支付成功后,自动跳转到商户网站:</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+联系银联业务运营部门开通商户号的自动跳转功能。<br>
+</p>
+
+<h4>5. 透传字段</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+  'reqReserved' =>'透传信息', //请求方保留域,透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自 己希望透传的数据<br>
+</p>
+
+<h4>-------------通知报文---------------------</h4>
+<h4>6. 返回报文中返回卡号,卡类型,支付方式:</h4>
+<p class="faq">
+【适用PC端网页,wap支付】<br>
+需在申请入网或者已经入网后给银联业务运营中心申请开通这3种权限<br>
+
+</p>

+ 17 - 0
application/common/library/upacp_demo_b2c/pages/dev_faq.php

@@ -0,0 +1,17 @@
+<h4>常见php问题:</h4>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=194&level=0&from=0" target="_blank">Call to undefined function openssl_pkcs12_read()</a>
+</p>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=182&level=0&from=0" target="_blank">windows版的php如何开启openssl</a>
+</p>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=190&level=0&from=0" target="_blank">supplied parameter cannot be coerced into an X509 certificate</a>
+</p>
+<p class="faq">
+<a href="https://open.unionpay.com/ajweb/help/faq/list?id=183&level=0&from=0" target="_blank">没有找到证书ID为[3474813271258769001041842579301293446]的证书</a>
+</p>
+
+<hr />
+<?php include $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2c/pages/more_faq.php';?>
+

+ 7 - 0
application/common/library/upacp_demo_b2c/pages/more_faq.php

@@ -0,0 +1,7 @@
+<h4>更多问题请使用open网站查找...</h4>
+<p class="faq">
+带7位应答码的错误请在 open网站-技术集成-应答码<a  href="https://open.unionpay.com/ajweb/help/respCode/respCodeList" target="_blank"> https://open.unionpay.com/ajweb/help/respCode/respCodeList</a>中搜索解决方法
+</p>
+<p class="faq">
+ 其他问题请在 open网站-帮助中心-FAQ<a href="https://open.unionpay.com/ajweb/help/faq/list" target="_blank"> https://open.unionpay.com/ajweb/help/faq/list</a>中搜索解决方法
+</p>

+ 131 - 0
application/common/library/upacp_demo_b2c/sdk/SDKConfig.php

@@ -0,0 +1,131 @@
+<?php
+namespace com\unionpay\acp\sdk;;
+include_once 'log.class.php';
+include_once 'common.php';
+
+class SDKConfig {
+	
+	private static $_config = null;
+	public static function getSDKConfig(){
+		if (SDKConfig::$_config == null ) {
+			SDKConfig::$_config = new SDKConfig();
+		}
+		return SDKConfig::$_config;
+	}
+	
+	private $frontTransUrl;
+	private $backTransUrl;
+	private $singleQueryUrl;
+	private $batchTransUrl;
+	private $fileTransUrl;
+	private $appTransUrl;
+	private $cardTransUrl;
+	private $orderTransUrl;
+	private $jfFrontTransUrl;
+	private $jfBackTransUrl;
+	private $jfSingleQueryUrl;
+	private $jfCardTransUrl;
+	private $jfAppTransUrl;
+	private $qrcBackTransUrl;
+	private $qrcB2cIssBackTransUrl;
+	private $qrcB2cMerBackTransUrl;
+	private $zhrzFrontTransUrl;
+	private $zhrzBackTransUrl;
+	private $zhrzSingleQueryUrl;
+	private $zhrzBatchTransUrl;
+	private $zhrzAppTransUrl;
+	private $zhrzFaceTransUrl;
+	
+	private $signMethod;
+	private $version;
+	private $ifValidateCNName;
+	private $ifValidateRemoteCert;
+	
+	private $signCertPath;
+	private $signCertPwd;
+	private $validateCertDir;
+	private $encryptCertPath;
+	private $rootCertPath;
+	private $middleCertPath;
+	private $frontUrl;
+	private $frontFailUrl;
+	private $backUrl;
+	private $secureKey;
+	private $logFilePath;
+	private $logLevel;
+
+	function __construct(){
+
+		//如果想把acp_sdk.ini挪到其他路径的话,请修改下面这行指定绝对路径。
+		$configFilePath = dirname(__FILE__) . "/acp_sdk.ini";
+		
+		if(!file_exists($configFilePath)){
+			$logger = LogUtil::getLogger();
+			$logger->LogError("配置文件加载失败,文件路径:[" . $configFilePath . "].请检查启动php的用户是否有读权限。");
+			return;
+		}
+		$ini_array = parse_ini_file($configFilePath, true);
+		$sdk_array = $ini_array["acpsdk"];
+		$this->frontTransUrl = array_key_exists("acpsdk.frontTransUrl", $sdk_array)?$sdk_array["acpsdk.frontTransUrl"] : null;
+		$this->backTransUrl = array_key_exists("acpsdk.backTransUrl", $sdk_array)?$sdk_array["acpsdk.backTransUrl"] : null;
+		$this->singleQueryUrl = array_key_exists("acpsdk.singleQueryUrl", $sdk_array)?$sdk_array["acpsdk.singleQueryUrl"] : null;
+		$this->batchTransUrl = array_key_exists("acpsdk.batchTransUrl", $sdk_array)?$sdk_array["acpsdk.batchTransUrl"] : null;
+		$this->fileTransUrl = array_key_exists("acpsdk.fileTransUrl", $sdk_array)?$sdk_array["acpsdk.fileTransUrl"] : null;
+		$this->appTransUrl = array_key_exists("acpsdk.appTransUrl", $sdk_array)?$sdk_array["acpsdk.appTransUrl"] : null;
+		$this->cardTransUrl = array_key_exists("acpsdk.cardTransUrl", $sdk_array)?$sdk_array["acpsdk.cardTransUrl"] : null;
+		$this->orderTransUrl = array_key_exists("acpsdk.orderTransUrl", $sdk_array)?$sdk_array["acpsdk.orderTransUrl"] : null;
+		
+		$this->jfFrontTransUrl = array_key_exists("acpsdk.jfFrontTransUrl", $sdk_array)?$sdk_array["acpsdk.jfFrontTransUrl"] : null;
+		$this->jfBackTransUrl = array_key_exists("acpsdk.jfBackTransUrl", $sdk_array)?$sdk_array["acpsdk.jfBackTransUrl"] : null;
+		$this->jfSingleQueryUrl = array_key_exists("acpsdk.jfSingleQueryUrl", $sdk_array)?$sdk_array["acpsdk.jfSingleQueryUrl"] : null;
+		$this->jfCardTransUrl = array_key_exists("acpsdk.jfCardTransUrl", $sdk_array)?$sdk_array["acpsdk.jfCardTransUrl"] : null;
+		$this->jfAppTransUrl = array_key_exists("acpsdk.jfAppTransUrl", $sdk_array)?$sdk_array["acpsdk.jfAppTransUrl"] : null;
+		
+		$this->qrcBackTransUrl = array_key_exists("acpsdk.qrcBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcBackTransUrl"] : null;
+		$this->qrcB2cIssBackTransUrl = array_key_exists("acpsdk.qrcB2cIssBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cIssBackTransUrl"] : null;
+		$this->qrcB2cMerBackTransUrl = array_key_exists("acpsdk.qrcB2cMerBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cMerBackTransUrl"] : null;
+		$this->zhrzFrontTransUrl = array_key_exists("acpsdk.zhrzFrontTransUrl", $sdk_array)?$sdk_array["acpsdk.zhrzFrontTransUrl"] : null;
+		$this->zhrzBackTransUrl = array_key_exists("acpsdk.zhrzBackTransUrl", $sdk_array)?$sdk_array["acpsdk.zhrzBackTransUrl"] : null;
+		$this->zhrzSingleQueryUrl = array_key_exists("acpsdk.zhrzSingleQueryUrl", $sdk_array)?$sdk_array["acpsdk.zhrzSingleQueryUrl"] : null;
+		$this->zhrzBatchTransUrl = array_key_exists("acpsdk.zhrzBatchTransUrl", $sdk_array)?$sdk_array["acpsdk.zhrzBatchTransUrl"] : null;
+		$this->zhrzAppTransUrl = array_key_exists("acpsdk.zhrzAppTransUrl", $sdk_array)?$sdk_array["acpsdk.zhrzAppTransUrl"] : null;
+		$this->zhrzFaceTransUrl = array_key_exists("acpsdk.zhrzFaceTransUrl", $sdk_array)?$sdk_array["acpsdk.zhrzFaceTransUrl"] : null;
+		
+		$this->signMethod = array_key_exists("acpsdk.signMethod", $sdk_array)?$sdk_array["acpsdk.signMethod"] : null;
+		$this->version = array_key_exists("acpsdk.version", $sdk_array)?$sdk_array["acpsdk.version"] : null;
+		$this->ifValidateCNName = array_key_exists("acpsdk.ifValidateCNName", $sdk_array)?$sdk_array["acpsdk.ifValidateCNName"] : "true";
+		$this->ifValidateRemoteCert = array_key_exists("acpsdk.ifValidateRemoteCert", $sdk_array)?$sdk_array["acpsdk.ifValidateRemoteCert"] : "false";
+					
+		$this->signCertPath = array_key_exists("acpsdk.signCert.path", $sdk_array)?$sdk_array["acpsdk.signCert.path"]: null;
+		$this->signCertPwd = array_key_exists("acpsdk.signCert.pwd", $sdk_array)?$sdk_array["acpsdk.signCert.pwd"]: null;
+		
+		$this->validateCertDir = array_key_exists("acpsdk.validateCert.dir", $sdk_array)? $sdk_array["acpsdk.validateCert.dir"]: null;
+		$this->encryptCertPath = array_key_exists("acpsdk.encryptCert.path", $sdk_array)? $sdk_array["acpsdk.encryptCert.path"]: null;
+		$this->rootCertPath = array_key_exists("acpsdk.rootCert.path", $sdk_array)? $sdk_array["acpsdk.rootCert.path"]: null;
+		$this->middleCertPath =  array_key_exists("acpsdk.middleCert.path", $sdk_array)?$sdk_array["acpsdk.middleCert.path"]: null;
+		
+		$this->frontUrl =  array_key_exists("acpsdk.frontUrl", $sdk_array)?$sdk_array["acpsdk.frontUrl"]: null;
+		$this->frontFailUrl =  array_key_exists("acpsdk.frontFailUrl", $sdk_array)?$sdk_array["acpsdk.frontFailUrl"]: null;
+		$this->backUrl =  array_key_exists("acpsdk.backUrl", $sdk_array)?$sdk_array["acpsdk.backUrl"]: null;
+		
+		$this->secureKey =  array_key_exists("acpsdk.secureKey", $sdk_array)?$sdk_array["acpsdk.secureKey"]: null;
+		$this->logFilePath =  array_key_exists("acpsdk.log.file.path", $sdk_array)?$sdk_array["acpsdk.log.file.path"]: null;
+		$this->logLevel =  array_key_exists("acpsdk.log.level", $sdk_array)?$sdk_array["acpsdk.log.level"]: null;
+		
+	}
+
+	public function __get($property_name)
+	{
+		if(isset($this->$property_name))
+		{
+			return($this->$property_name);
+		}
+		else
+		{
+			return(NULL);
+		}
+	}
+
+}
+
+

+ 75 - 0
application/common/library/upacp_demo_b2c/sdk/acp_sdk.ini

@@ -0,0 +1,75 @@
+;;;;;;;;;;;;;;SDK配置文件(证书方式签名);;;;;;;;;;;;;;;;
+; 说明:
+; 1. 使用时请将此文件复制到根文件夹下替换原来的acp_sdk.ini。
+; 2. 具体配置项请根据注释修改。
+; 3. sdk默认读取的配置文件路径为sdk文件夹的acp_sdk.ini文件,如果需修改路径,请自行到sdk/SDKConfig.php中修改。
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[acpsdk]
+;;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址);;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;交易请求地址
+acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do
+acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do
+acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do
+acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do
+acpsdk.fileTransUrl=https://filedownload.test.95516.com/
+acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do
+acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do
+acpsdk.orderTransUrl=https://gateway.test.95516.com/gateway/api/order.do
+
+;以下缴费产品使用,其余产品用不到
+acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do
+acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do
+acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do
+acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do
+acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; 报文版本号,固定5.1.0,请勿改动
+acpsdk.version=5.1.0
+
+; 签名方式,证书方式固定01,请勿改动
+acpsdk.signMethod=01
+
+; 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。
+acpsdk.ifValidateCNName=false
+
+; 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。
+acpsdk.ifValidateRemoteCert=false
+
+;后台通知地址,填写接收银联后台通知的地址,必须外网能访问
+acpsdk.backUrl=http://222.222.222.222:8080/upacp_demo_b2c/demo/api_01_gateway/BackReceive.php
+
+;前台通知地址,填写处理银联前台通知的地址,必须外网能访问
+acpsdk.frontUrl=http://localhost:8086/upacp_demo_b2c/demo/api_01_gateway/FrontReceive.php
+
+;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境签名证书配置 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 多证书的情况证书路径为代码指定,可不对此块做配置。
+; 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。
+; 测试环境证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹。生产环境证书由业务部门邮件发送。
+; windows样例:
+acpsdk.signCert.path=D:/certs/acp_test_sign.pfx
+; linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明)
+;acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp_test_sign.pfx
+
+; 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败
+acpsdk.signCert.pwd=000000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;加密证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用)
+acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;验签证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 验签中级证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.middleCert.path=D:/certs/acp_test_middle.cer
+; 验签根证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹)
+acpsdk.rootCert.path=D:/certs/acp_test_root.cer
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;日志配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 日志打印路径,linux注意要有写权限
+acpsdk.log.file.path=D:/logs/
+; 日志级别,debug级别会打印密钥,生产请用info或以上级别
+acpsdk.log.level=DEBUG

+ 538 - 0
application/common/library/upacp_demo_b2c/sdk/acp_service.php

@@ -0,0 +1,538 @@
+<?php
+namespace com\unionpay\acp\sdk;
+header ( 'Content-type:text/html;charset=utf-8' );
+include_once 'log.class.php';
+include_once 'SDKConfig.php';
+include_once 'common.php';
+include_once 'cert_util.php';
+
+class AcpService {
+
+	/**
+	 *
+	 * 更新证书
+	 *
+	 * Enter description here ...
+	 */
+	public static function updateEncryptCert(&$params)
+	{
+        $logger = LogUtil::getLogger();
+		// 取得证书
+		$strCert = $params['encryptPubKeyCert'];
+		$certType = $params['certType'];
+		openssl_x509_read($strCert);
+		$certInfo = openssl_x509_parse($strCert);
+		if($certType === "01"){
+			$logger->LogInfo ('原证书certId:'.CertUtil::getEncryptCertId().',新证书certId:'.$certInfo['serialNumber']);
+			// 更新敏感信息加密公钥
+			if (CertUtil::getEncryptCertId() != $certInfo['serialNumber']) {
+				$newFileName = getBackupFileName(SDKConfig::getSDKConfig()->encryptCertPath);
+				// 将原证书备份重命名
+				if(!copy(SDKConfig::getSDKConfig()->encryptCertPath, $newFileName)){
+					$logger->LogError ('原证书备份失败');
+					return -1;
+				}
+				// 更新证书
+				if(!file_put_contents(SDKConfig::getSDKConfig()->encryptCertPath, $strCert)){
+					$logger->LogError ('更新证书失败');
+					return -1;
+				}
+				$logger->LogInfo ('证书更新成功');
+				return 1;
+			} else {						
+				$logger->LogInfo ('证书无需更新');
+				return 0;
+			}
+		} else if($certType === "02"){
+			return 0;
+		} else {						
+			$logger->LogError ('unknown cerType: '. $certType);
+			return -1;
+		}
+	}
+
+	/**
+	 * 签名
+	 * @param req 请求要素
+	 * @param resp 应答要素
+	 * @return 是否成功
+	 */
+	static function sign(&$params) {
+		if($params['signMethod']=='01')	{
+			return AcpService::signByCertInfo($params, SDKConfig::getSDKConfig()->signCertPath, SDKConfig::getSDKConfig()->signCertPwd);
+		} else {
+			return AcpService::signBySecureKey($params, SDKConfig::getSDKConfig()->secureKey);
+		} 
+	}
+	
+	static function signByCertInfo(&$params, $cert_path, $cert_pwd) {
+
+		$logger = LogUtil::getLogger();
+		$logger->LogInfo ( '=====签名报文开始======' );
+		if(isset($params['signature'])){
+			unset($params['signature']);
+		}
+		
+		$result = false;
+		
+		if($params['signMethod']=='01') {
+			//证书ID
+			$params ['certId'] = CertUtil::getSignCertIdFromPfx($cert_path, $cert_pwd);
+			$private_key = CertUtil::getSignKeyFromPfx( $cert_path, $cert_pwd );
+			// 转换成key=val&串
+			$params_str = createLinkString ( $params, true, false );
+			$logger->LogInfo ( "签名key=val&...串 >" . $params_str );
+			if($params['version']=='5.0.0'){
+				$params_sha1x16 = sha1 ( $params_str, FALSE );
+				$logger->LogInfo ( "摘要sha1x16 >" . $params_sha1x16 );
+				// 签名
+				$result = openssl_sign ( $params_sha1x16, $signature, $private_key, OPENSSL_ALGO_SHA1);
+		
+				if ($result) {
+					$signature_base64 = base64_encode ( $signature );
+					$logger->LogInfo ( "签名串为 >" . $signature_base64 );
+					$params ['signature'] = $signature_base64;
+				} else {
+					$logger->LogInfo ( ">>>>>签名失败<<<<<<<" );
+				}
+			} else if($params['version']=='5.1.0'){
+				//sha256签名摘要
+				$params_sha256x16 = hash( 'sha256',$params_str);
+				$logger->LogInfo ( "摘要sha256x16 >" . $params_sha256x16 );
+				// 签名
+				$result = openssl_sign ( $params_sha256x16, $signature, $private_key, 'sha256');
+				if ($result) {
+					$signature_base64 = base64_encode ( $signature );
+					$logger->LogInfo ( "签名串为 >" . $signature_base64 );
+					$params ['signature'] = $signature_base64;
+				} else {
+					$logger->LogInfo ( ">>>>>签名失败<<<<<<<" );
+				}
+			} else {
+				$logger->LogError ( "wrong version: " . $params['version'] );
+				$result = false;
+			}
+		} else {
+			$logger->LogError ( "signMethod不正确");
+			$result = false;
+		}
+		$logger->LogInfo ( '=====签名报文结束======' );
+		return $result;
+	}
+	
+	static function signBySecureKey(&$params, $secureKey) {
+		
+		$logger = LogUtil::getLogger();
+		
+		if($secureKey == null || trim($secureKey) == '') {
+			$logger->LogError ( "密钥没配,签名失败");
+			return false;
+		}
+		
+		$logger->LogInfo ( '=====签名报文开始======' );
+		
+		if($params['signMethod']=='11') {
+			// 转换成key=val&串
+			$params_str = createLinkString ( $params, true, false );
+			$logger->LogInfo ( "签名key=val&...串 >" . $params_str );
+			$params_before_sha256 = hash('sha256', $secureKey);
+			$params_before_sha256 = $params_str.'&'.$params_before_sha256;
+			$logger->LogDebug( "before final sha256: " . $params_before_sha256);
+			$params_after_sha256 = hash('sha256',$params_before_sha256);
+			$logger->LogInfo ( "签名串为 >" . $params_after_sha256 );
+			$params ['signature'] = $params_after_sha256;
+			$result = true;
+		} else if($params['signMethod']=='12') {
+			//TODO SM3
+			$logger->LogError ( "signMethod=12未实现");
+			$result = false;
+		} else {
+			$logger->LogError ( "signMethod不正确");
+			$result = false;
+		}
+		$logger->LogInfo ( '=====签名报文结束======' );
+		return $result;
+	}
+
+	/**
+	 * 验签
+	 * @param $params 应答数组
+	 * @return 是否成功
+	 */
+	static function validate($params) {
+
+		$logger = LogUtil::getLogger();
+
+		$isSuccess = false;
+
+		if($params['signMethod']=='01')
+		{
+			$signature_str = $params ['signature'];
+			unset ( $params ['signature'] );
+			$params_str = createLinkString ( $params, true, false );
+			$logger->LogInfo ( '报文去[signature] key=val&串>' . $params_str );
+			$logger->LogInfo ( '签名原文>' . $signature_str );
+			if($params['version']=='5.0.0'){
+
+				// 公钥
+				$public_key = CertUtil::getVerifyCertByCertId ( $params ['certId'] );
+				$signature = base64_decode ( $signature_str );
+				$params_sha1x16 = sha1 ( $params_str, FALSE );
+				$logger->LogInfo ( 'sha1>' . $params_sha1x16 );
+				$isSuccess = openssl_verify ( $params_sha1x16, $signature, $public_key, OPENSSL_ALGO_SHA1 );
+				$logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' );
+
+			} else if($params['version']=='5.1.0'){
+
+				$strCert = $params['signPubKeyCert'];
+				$strCert = CertUtil::verifyAndGetVerifyCert($strCert);
+				if($strCert == null){
+                	$logger->LogError ("validate cert err: " . $params["signPubKeyCert"]);
+					$isSuccess = false;
+				} else {
+					$params_sha256x16 = hash('sha256', $params_str);
+					$logger->LogInfo ( 'sha256>' . $params_sha256x16 );
+					$signature = base64_decode ( $signature_str );
+					$isSuccess = openssl_verify ( $params_sha256x16, $signature,$strCert, "sha256" );
+					$logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' );
+				}
+
+			} else {
+				$logger->LogError ( "wrong version: " . $params['version'] );
+				$isSuccess = false;
+			}
+		} else {
+			$isSuccess = AcpService::validateBySecureKey($params, SDKConfig::getSDKConfig()->secureKey);
+		} 
+		return $isSuccess;
+	}
+
+	static function validateBySecureKey($params, $secureKey) { 
+		
+		$logger = LogUtil::getLogger();
+		
+		if($secureKey == null || trim($secureKey) == '') {
+			$logger->LogError ( "密钥没配,验签失败");
+			return false;
+		}
+		$isSuccess = false;
+		
+		$signature_str = $params ['signature'];
+		unset ( $params ['signature'] );
+		$params_str = createLinkString ( $params, true, false );
+		$logger->LogInfo ( '报文去[signature] key=val&串>' . $params_str );
+		$logger->LogInfo ( '签名原文>' . $signature_str );
+		
+		if($params['signMethod']=='11') {
+			
+			$params_before_sha256 = hash('sha256', $secureKey);
+			$params_before_sha256 = $params_str.'&'.$params_before_sha256;
+			$params_after_sha256 = hash('sha256',$params_before_sha256);
+			$isSuccess = $params_after_sha256 == $signature_str;
+			$logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' );
+		} else if($params['signMethod']=='12') {
+			//TODO SM3
+			$logger->LogError ( "sm3没实现");
+			$isSuccess = false;
+		} else {
+			$logger->LogError ( "signMethod不正确");
+			$isSuccess = false;
+		}
+
+		return $isSuccess;
+		
+	}
+	
+	/**
+	 * @deprecated 5.1.0开发包已删除此方法,请直接参考5.1.0开发包中的VerifyAppData.php验签。
+	 * 对控件支付成功返回的结果信息中data域进行验签
+	 * @param $jsonData json格式数据,例如:{"sign" : "J6rPLClQ64szrdXCOtV1ccOMzUmpiOKllp9cseBuRqJ71pBKPPkZ1FallzW18gyP7CvKh1RxfNNJ66AyXNMFJi1OSOsteAAFjF5GZp0Xsfm3LeHaN3j/N7p86k3B1GrSPvSnSw1LqnYuIBmebBkC1OD0Qi7qaYUJosyA1E8Ld8oGRZT5RR2gLGBoiAVraDiz9sci5zwQcLtmfpT5KFk/eTy4+W9SsC0M/2sVj43R9ePENlEvF8UpmZBqakyg5FO8+JMBz3kZ4fwnutI5pWPdYIWdVrloBpOa+N4pzhVRKD4eWJ0CoiD+joMS7+C0aPIEymYFLBNYQCjM0KV7N726LA==",  "data" : "pay_result=success&tn=201602141008032671528&cert_id=68759585097"}
+	 * @return 是否成功
+	 */
+	static function validateAppResponse($jsonData) {
+
+		$data = json_decode($jsonData);
+		$sign = $data->sign;
+		$data = $data->data;
+		$dataMap = parseQString($data);
+		$public_key = CertUtil::getVerifyCertByCertId( $dataMap ['cert_id'] );
+		$signature = base64_decode ( $sign );
+		$params_sha1x16 = sha1 ( $data, FALSE );
+		$isSuccess = openssl_verify ( $params_sha1x16, $signature,$public_key, OPENSSL_ALGO_SHA1 );
+		return $isSuccess;
+	}
+
+	/**
+	 * 后台交易 HttpClient通信
+	 *
+	 * @param unknown_type $params
+	 * @param unknown_type $url
+	 * @return mixed
+	 */
+	static function post($params, $url) {
+		$logger = LogUtil::getLogger();
+
+		$opts = createLinkString ( $params, false, true );
+		$logger->LogInfo ( "后台请求地址为>" . $url );
+		$logger->LogInfo ( "后台请求报文为>" . $opts );
+
+		$ch = curl_init ();
+		curl_setopt ( $ch, CURLOPT_URL, $url );
+		curl_setopt ( $ch, CURLOPT_POST, 1 );
+		curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); // 不验证证书
+		curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false ); // 不验证HOST
+		curl_setopt ( $ch, CURLOPT_SSLVERSION, 1 ); // http://php.net/manual/en/function.curl-setopt.php页面搜CURL_SSLVERSION_TLSv1
+		curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
+				'Content-type:application/x-www-form-urlencoded;charset=UTF-8' 
+				) );
+				curl_setopt ( $ch, CURLOPT_POSTFIELDS, $opts );
+				curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
+				$html = curl_exec ( $ch );
+				$logger->LogInfo ( "后台返回结果为>" . $html );
+
+				if(curl_errno($ch)){
+					$errmsg = curl_error($ch);
+					curl_close ( $ch );
+					$logger->LogInfo ( "请求失败,报错信息>" . $errmsg );
+					return null;
+				}
+				if( curl_getinfo($ch, CURLINFO_HTTP_CODE) != "200"){
+					$errmsg = "http状态=" . curl_getinfo($ch, CURLINFO_HTTP_CODE);
+					curl_close ( $ch );
+					$logger->LogInfo ( "请求失败,报错信息>" . $errmsg );
+					return null;
+				}
+				curl_close ( $ch );
+				$result_arr = convertStringToArray ( $html );
+				return $result_arr;
+	}
+
+	/**
+	 * 后台交易 HttpClient通信
+	 *
+	 * @param unknown_type $params
+	 * @param unknown_type $url
+	 * @return mixed
+	 */
+	static function get($params, $url) {
+
+		$logger = LogUtil::getLogger();
+
+		$opts = createLinkString ( $params, false, true );
+		$logger->LogDebug( "后台请求地址为>" . $url ); //get的日志太多而且没啥用,设debug级别
+		$logger->LogDebug ( "后台请求报文为>" . $opts );
+
+		$ch = curl_init ();
+		curl_setopt ( $ch, CURLOPT_URL, $url );
+		curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); // 不验证证书
+		curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false ); // 不验证HOST
+		curl_setopt ( $ch, CURLOPT_SSLVERSION, 1 ); // http://php.net/manual/en/function.curl-setopt.php页面搜CURL_SSLVERSION_TLSv1
+		curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
+		'Content-type:application/x-www-form-urlencoded;charset=UTF-8'
+		) );
+		curl_setopt ( $ch, CURLOPT_POSTFIELDS, $opts );
+		curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
+		$html = curl_exec ( $ch );
+		$logger->LogInfo ( "后台返回结果为>" . $html );
+		if(curl_errno($ch)){
+			$errmsg = curl_error($ch);
+			curl_close ( $ch );
+			$logger->LogDebug ( "请求失败,报错信息>" . $errmsg );
+			return null;
+		}
+		if( curl_getinfo($ch, CURLINFO_HTTP_CODE) != "200"){
+			$errmsg = "http状态=" . curl_getinfo($ch, CURLINFO_HTTP_CODE);
+			curl_close ( $ch );
+			$logger->LogDebug ( "请求失败,报错信息>" . $errmsg );
+			return null;
+		}
+		curl_close ( $ch );
+		return $html;
+	}
+
+	static function createAutoFormHtml($params, $reqUrl) {
+		// <body onload="javascript:document.pay_form.submit();">
+		$encodeType = isset ( $params ['encoding'] ) ? $params ['encoding'] : 'UTF-8';
+		$html = <<<eot
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset={$encodeType}" />
+</head>
+<body onload="javascript:document.pay_form.submit();">
+    <form id="pay_form" name="pay_form" action="{$reqUrl}" method="post">
+	
+eot;
+		foreach ( $params as $key => $value ) {
+			$html .= "    <input type=\"hidden\" name=\"{$key}\" id=\"{$key}\" value=\"{$value}\" />\n";
+		}
+		$html .= <<<eot
+   <!-- <input type="submit" type="hidden">-->
+    </form>
+</body>
+</html>
+eot;
+		$logger = LogUtil::getLogger();
+		$logger->LogInfo ( "自动跳转html>" . $html );
+		return $html;
+	}
+
+
+
+	static function getCustomerInfo($customerInfo) {
+		if($customerInfo == null || count($customerInfo) == 0 )
+		return "";
+		return base64_encode ( "{" . createLinkString ( $customerInfo, false, false ) . "}" );
+	}
+
+	/**
+	 * map转换string,敏感信息加密
+	 *
+	 * @param
+	 *        	$customerInfo
+	 */
+	static function getCustomerInfoWithEncrypt($customerInfo) {
+		if($customerInfo == null || count($customerInfo) == 0 )
+		return "";
+		$encryptedInfo = array();
+		foreach ( $customerInfo as $key => $value ) {
+			if ($key == 'phoneNo' || $key == 'cvn2' || $key == 'expired' ) {
+				//if ($key == 'phoneNo' || $key == 'cvn2' || $key == 'expired' || $key == 'certifTp' || $key == 'certifId') {
+				$encryptedInfo [$key] = $customerInfo [$key];
+				unset ( $customerInfo [$key] );
+			}
+		}
+		if( count ($encryptedInfo) > 0 ){
+			$encryptedInfo = createLinkString ( $encryptedInfo, false, false );
+			$encryptedInfo = AcpService::encryptData ( $encryptedInfo, SDKConfig::getSDKConfig()->encryptCertPath );
+			$customerInfo ['encryptedInfo'] = $encryptedInfo;
+		}
+		return base64_encode ( "{" . createLinkString ( $customerInfo, false, false ) . "}" );
+	}
+
+
+	/**
+	 * 解析customerInfo。
+	 * 为方便处理,encryptedInfo下面的信息也均转换为customerInfo子域一样方式处理,
+	 * @param unknown $customerInfostr
+	 * @return array形式ParseCustomerInfo
+	 */
+	static function parseCustomerInfo($customerInfostr) {
+		$customerInfostr = base64_decode($customerInfostr);
+		$customerInfostr = substr($customerInfostr, 1, strlen($customerInfostr) - 2);
+		$customerInfo = parseQString($customerInfostr);
+		if(array_key_exists("encryptedInfo", $customerInfo)) {
+			$encryptedInfoStr = $customerInfo["encryptedInfo"];
+			unset ( $customerInfo ["encryptedInfo"] );
+			$encryptedInfoStr = AcpService::decryptData($encryptedInfoStr);
+			$encryptedInfo = parseQString($encryptedInfoStr);
+			foreach ($encryptedInfo as $key => $value){
+				$customerInfo[$key] = $value;
+			}
+		}
+		return $customerInfo;
+	}
+
+	static function getEncryptCertId() {
+		$cert_path=SDKConfig::getSDKConfig()->encryptCertPath;
+		return CertUtil::getEncryptCertId($cert_path);
+	}
+
+	/**
+	 * 加密数据
+	 * @param string $data数据
+	 * @param string $cert_path 证书配置路径
+	 * @return unknown
+	 */
+	static function encryptData($data, $cert_path=null) {
+		if( $cert_path == null ) {
+			$cert_path = SDKConfig::getSDKConfig()->encryptCertPath;
+		}
+		$public_key = CertUtil::getEncryptKey( $cert_path );
+		openssl_public_encrypt ( $data, $crypted, $public_key );
+		return base64_encode ( $crypted );
+	}
+
+	/**
+	 * 解密数据
+	 * @param string $data数据
+	 * @param string $cert_path 证书配置路径
+	 * @return unknown
+	 */
+	static function decryptData($data, $cert_path=null, $cert_pwd=null) {
+
+		if( $cert_path == null ) {
+			$cert_path = SDKConfig::getSDKConfig()->signCertPath;
+			$cert_pwd = SDKConfig::getSDKConfig()->signCertPwd;
+		}
+		
+		$data = base64_decode ( $data );
+		$private_key = CertUtil::getSignKeyFromPfx ( $cert_path, $cert_pwd);
+		openssl_private_decrypt ( $data, $crypted, $private_key );
+		return $crypted;
+	}
+
+
+	/**
+	 * 处理报文中的文件
+	 *
+	 * @param unknown_type $params
+	 */
+	static function deCodeFileContent($params, $fileDirectory) {
+		$logger = LogUtil::getLogger();
+		if (isset ( $params ['fileContent'] )) {
+			$logger->LogInfo ( "---------处理后台报文返回的文件---------" );
+			$fileContent = $params ['fileContent'];
+
+			if (empty ( $fileContent )) {
+				$logger->LogInfo ( '文件内容为空' );
+				return false;
+			} else {
+				// 文件内容 解压缩
+				$content = gzuncompress ( base64_decode ( $fileContent ) );
+				$filePath = null;
+				if (empty ( $params ['fileName'] )) {
+					$logger->LogInfo ( "文件名为空" );
+					$filePath = $fileDirectory . $params ['merId'] . '_' . $params ['batchNo'] . '_' . $params ['txnTime'] . '.txt';
+				} else {
+					$filePath = $fileDirectory . $params ['fileName'];
+				}
+				$handle = fopen ( $filePath, "w+" );
+				if (! is_writable ( $filePath )) {
+					$logger->LogInfo ( "文件:" . $filePath . "不可写,请检查!" );
+					return false;
+				} else {
+					file_put_contents ( $filePath, $content );
+					$logger->LogInfo ( "文件位置 >:" . $filePath );
+				}
+				fclose ( $handle );
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 功能:将批量文件内容使用DEFLATE压缩算法压缩,Base64编码生成字符串并返回
+	 * 适用到的交易:批量代付,批量代收,批量退货
+	 * @param unknown $path
+	 * @return boolean|string
+	 */
+	static function enCodeFileContent($path){
+
+		$file_content_base64 = '';
+		if(!file_exists($path)){
+			echo '文件没找到';
+			return false;
+		}
+
+		$file_content = file_get_contents ( $path );
+		//UTF8 去掉文本中的 bom头
+		$BOM = chr(239).chr(187).chr(191);
+		$file_content = str_replace($BOM,'',$file_content);
+		$file_content_deflate = gzcompress ( $file_content );
+		$file_content_base64 = base64_encode ( $file_content_deflate );
+		return $file_content_base64;
+	}
+}
+

+ 411 - 0
application/common/library/upacp_demo_b2c/sdk/cert_util.php

@@ -0,0 +1,411 @@
+<?php
+namespace com\unionpay\acp\sdk;
+
+include_once 'acp_service.php';
+
+const COMPANY = "中国银联股份有限公司";
+class Cert
+{
+    public $cert;
+    public $certId;
+    public $key;
+}
+
+
+// 内存泄漏问题说明:
+//     openssl_x509_parse疑似有内存泄漏,暂不清楚原因,可能和php、openssl版本有关,估计有bug。
+//     windows下试过php5.4+openssl0.9.8,php7.0+openssl1.0.2都有这问题。mac下试过也有问题。
+//     不过至今没人来反馈过这个问题,所以不一定真有泄漏?或者因为增长量不大所以一般都不会遇到问题?
+//     也有别人汇报过bug:https://bugs.php.net/bug.php?id=71519
+//
+// 替代解决方案:
+//     方案1. 所有调用openssl_x509_parse的地方都是为了获取证书序列号,可以尝试把证书序列号+证书/key以别的方式保存,
+//            从其他地方(比如数据库)读序列号,而不直接从证书文件里读序列号。
+//     方案2. 代码改成执行脚本的方式执行,这样执行完一次保证能释放掉所有内存。
+//     方案3. 改用下面的CertSerialUtil取序列号,
+//            此方法仅用了几个测试和生产的证书做过测试,不保证没bug,所以默认注释掉了。如发现有bug或者可优化的地方可自行修改代码。
+//            注意用了bcmath的方法,*nix下编译时需要 --enable-bcmath。http://php.net/manual/zh/bc.installation.php
+
+
+class CertUtil{
+
+    private static $signCerts = array();
+    private static $encryptCerts = array();
+    private static $verifyCerts = array();
+    private static $verifyCerts510 = array();
+
+    private static function initSignCert($certPath, $certPwd){
+        $logger = LogUtil::getLogger();
+        $logger->LogInfo("读取签名证书……");
+
+        $pkcs12certdata = file_get_contents ( $certPath );
+        if($pkcs12certdata === false ){
+        	$logger->LogInfo($certPath . "file_get_contents fail。");
+        	return;
+        }
+        
+        if(openssl_pkcs12_read ( $pkcs12certdata, $certs, $certPwd ) == FALSE ){
+        	$logger->LogInfo($certPath . ", pwd[" . $certPwd . "] openssl_pkcs12_read fail。");
+        	return;
+        }
+        
+        $cert = new Cert();
+        $x509data = $certs ['cert'];
+
+        if(!openssl_x509_read ( $x509data )){
+        	$logger->LogInfo($certPath . " openssl_x509_read fail。");
+        }
+        $certdata = openssl_x509_parse ( $x509data );
+        $cert->certId = $certdata ['serialNumber'];
+
+// 		$certId = CertSerialUtil::getSerial($x509data, $errMsg);
+// 		if($certId === false){
+//         	$logger->LogInfo("签名证书读取序列号失败:" . $errMsg);
+//         	return;
+// 		}
+//         $cert->certId = $certId;
+        
+        $cert->key = $certs ['pkey'];
+        $cert->cert = $x509data;
+
+        $logger->LogInfo("签名证书读取成功,序列号:" . $cert->certId);
+        CertUtil::$signCerts[$certPath] = $cert;
+    }
+
+    public static function getSignKeyFromPfx($certPath=null, $certPwd=null)
+    {
+    	if( $certPath == null ) {
+    		$certPath = SDKConfig::getSDKConfig()->signCertPath;
+    		$certPwd = SDKConfig::getSDKConfig()->signCertPwd;
+    	}
+    	
+        if (!array_key_exists($certPath, CertUtil::$signCerts)) {
+            self::initSignCert($certPath, $certPwd);
+        }
+        return CertUtil::$signCerts[$certPath] -> key;
+    }
+
+    public static function getSignCertIdFromPfx($certPath=null, $certPwd=null)
+    {
+
+    	if( $certPath == null ) {
+    		$certPath = SDKConfig::getSDKConfig()->signCertPath;
+    		$certPwd = SDKConfig::getSDKConfig()->signCertPwd;
+    	}
+    	
+        if (!array_key_exists($certPath, CertUtil::$signCerts)) {
+            self::initSignCert($certPath, $certPwd);
+        }
+        return CertUtil::$signCerts[$certPath] -> certId;
+    }
+
+    private static function initEncryptCert($cert_path)
+    {
+        $logger = LogUtil::getLogger();
+        $logger->LogInfo("读取加密证书……");
+        
+	    $x509data = file_get_contents ( $cert_path );
+        if($x509data === false ){
+        	$logger->LogInfo($cert_path . " file_get_contents fail。");
+        	return;
+        }
+	    
+	    if(!openssl_x509_read ( $x509data )){
+        	$logger->LogInfo($cert_path . " openssl_x509_read fail。");
+        	return;
+	    }
+
+	    $cert = new Cert();
+	    $certdata = openssl_x509_parse ( $x509data );
+	    $cert->certId = $certdata ['serialNumber'];
+
+// 	    $certId = CertSerialUtil::getSerial($x509data, $errMsg);
+// 	    if($certId === false){
+// 	    	$logger->LogInfo("签名证书读取序列号失败:" . $errMsg);
+// 	    	return;
+// 	    }
+// 	    $cert->certId = $certId;
+	    
+        $cert->key = $x509data;
+        CertUtil::$encryptCerts[$cert_path] = $cert;
+        $logger->LogInfo("加密证书读取成功,序列号:" . $cert->certId);
+    }
+    
+    public static function verifyAndGetVerifyCert($certBase64String){
+
+    	$logger = LogUtil::getLogger();
+    	
+    	if (array_key_exists($certBase64String, CertUtil::$verifyCerts510)){
+    		return CertUtil::$verifyCerts510[$certBase64String];
+    	}
+    	
+		if (SDKConfig::getSDKConfig()->middleCertPath === null || SDKConfig::getSDKConfig()->rootCertPath === null){
+			$logger->LogError("rootCertPath or middleCertPath is none, exit initRootCert");
+			return null;
+		}
+		openssl_x509_read($certBase64String);
+		$certInfo = openssl_x509_parse($certBase64String);
+		
+		$cn = CertUtil::getIdentitiesFromCertficate($certInfo);
+		if(strtolower(SDKConfig::getSDKConfig()->ifValidateCNName) == "true"){
+			if (COMPANY != $cn){
+				$logger->LogInfo("cer owner is not CUP:" . $cn);
+				return null;
+			}
+		} else if (COMPANY != $cn && "00040000:SIGN" != $cn){
+			$logger->LogInfo("cer owner is not CUP:" . $cn);
+			return null;
+		}
+		
+		$from = date_create ( '@' . $certInfo ['validFrom_time_t'] );
+		$to = date_create ( '@' . $certInfo ['validTo_time_t'] );
+		$now = date_create ( date ( 'Ymd' ) );
+		$interval1 = $from->diff ( $now );
+		$interval2 = $now->diff ( $to );
+		if ($interval1->invert || $interval2->invert) {
+			$logger->LogInfo("signPubKeyCert has expired");
+			return null;
+		}
+		 
+		$result = openssl_x509_checkpurpose($certBase64String, X509_PURPOSE_ANY, array(SDKConfig::getSDKConfig()->rootCertPath, SDKConfig::getSDKConfig()->middleCertPath));
+		if($result === FALSE){
+			$logger->LogInfo("validate signPubKeyCert by rootCert failed");
+			return null;
+		} else if($result === TRUE){
+			CertUtil::$verifyCerts510[$certBase64String] = $certBase64String;
+    		return CertUtil::$verifyCerts510[$certBase64String];
+		} else {
+			$logger->LogInfo("validate signPubKeyCert by rootCert failed with error");
+			return null;
+		}
+    }
+    
+    public static function getIdentitiesFromCertficate($certInfo){
+    	
+    	$cn = $certInfo['subject'];
+    	$cn = $cn['CN'];  	
+    	$company = explode('@',$cn);
+    	
+    	if(count($company) < 3) {
+    		return null;
+    	} 
+    	return $company[2];
+    }
+    
+    public static function getEncryptCertId($cert_path=null){
+    	if( $cert_path == null ) {
+    		$cert_path = SDKConfig::getSDKConfig()->encryptCertPath;
+    	}
+        if(!array_key_exists($cert_path, CertUtil::$encryptCerts)){
+            self::initEncryptCert($cert_path);
+        }
+        if(array_key_exists($cert_path, CertUtil::$encryptCerts)){
+        	return CertUtil::$encryptCerts[$cert_path] -> certId;
+        }
+        return false;
+    }
+
+    public static function getEncryptKey($cert_path=null){
+    	if( $cert_path == null ) {
+    		$cert_path = SDKConfig::getSDKConfig()->encryptCertPath;
+    	}
+        if(!array_key_exists($cert_path, CertUtil::$encryptCerts)){
+            self::initEncryptCert($cert_path);
+        }
+        if(array_key_exists($cert_path, CertUtil::$encryptCerts)){
+        	return CertUtil::$encryptCerts[$cert_path] -> key;
+        }
+        return false;
+    }
+
+    private static function initVerifyCerts($cert_dir=null) {
+
+    	if( $cert_dir == null ) {
+    		$cert_dir = SDKConfig::getSDKConfig()->validateCertDir;
+    	}
+    	
+        $logger = LogUtil::getLogger();
+        $logger->LogInfo ( '验证签名证书目录 :>' . $cert_dir );
+        $handle = opendir ( $cert_dir );
+        if (!$handle) {
+            $logger->LogInfo ( '证书目录 ' . $cert_dir . '不正确' );
+            return;
+        }
+        
+        while ($file = readdir($handle)) {
+            clearstatcache();
+            $filePath = $cert_dir . '/' . $file;
+            if (is_file($filePath)) {
+                if (pathinfo($file, PATHINFO_EXTENSION) == 'cer') {
+                	
+                    $x509data = file_get_contents($filePath);
+			        if($x509data === false ){
+			        	$logger->LogInfo($filePath . " file_get_contents fail。");
+                    	continue;
+			        }
+                    if(!openssl_x509_read($x509data)){
+                    	$logger->LogInfo($certPath . " openssl_x509_read fail。");
+                    	continue;
+                    }
+                    
+                    $cert = new Cert();
+                    $certdata = openssl_x509_parse($x509data);
+                    $cert->certId = $certdata ['serialNumber'];
+
+//                     $certId = CertSerialUtil::getSerial($x509data, $errMsg);
+//                     if($certId === false){
+//                     	$logger->LogInfo("签名证书读取序列号失败:" . $errMsg);
+//                     	return;
+//                     }
+//                     $cert->certId = $certId;
+
+                    $cert->key = $x509data;
+                    CertUtil::$verifyCerts[$cert->certId] = $cert;
+                    $logger->LogInfo($filePath . "读取成功,序列号:" . $cert->certId);
+                }
+            }
+        }
+        closedir ( $handle );
+    }
+
+    public static function getVerifyCertByCertId($certId){
+        $logger = LogUtil::getLogger();
+        if(count(CertUtil::$verifyCerts) == 0){
+            self::initVerifyCerts();
+        }
+        if(count(CertUtil::$verifyCerts) == 0){
+            $logger->LogInfo("未读取到任何证书……");
+            return null;
+        }
+        if(array_key_exists($certId, CertUtil::$verifyCerts)){
+            return CertUtil::$verifyCerts[$certId]->key;
+        } else {
+            $logger->LogInfo("未匹配到序列号为[" . certId . "]的证书");
+            return null;
+        }
+    }
+    
+	public static function test() {
+		
+		$x509data = file_get_contents ( "d:/certs/acp_test_enc.cer" );
+// 		$resource = openssl_x509_read ( $x509data );
+		// $certdata = openssl_x509_parse ( $resource ); //<=这句尼玛内存泄漏啊根本释放不掉啊啊啊啊啊啊啊
+		// echo $certdata ['serialNumber']; //<=就是需要这个数据啦
+		// echo $x509data;
+		// unset($certdata); //<=没有什么用
+		// openssl_x509_free($resource); //<=没有什么用x2
+		echo CertSerialUtil::getSerial ( $x509data, $errMsg ) . "\n";
+	}
+}
+
+
+
+// class CertSerialUtil {
+	 
+// 	private static function bytesToInteger($bytes) {
+// 		$val = 0;
+// 		for($i = 0; $i < count ( $bytes ); $i ++) {
+// // 			$val += (($bytes [$i] & 0xff) << (8 * (count ( $bytes ) - 1 - $i)));
+// 			$val += $bytes [$i] * pow(256, count ( $bytes ) - 1 - $i);
+// // 			echo $val . "<br>\n";
+// 		}
+// 		return $val;
+// 	}
+	
+// 	private static function bytesToBigInteger($bytes) {
+// 		$val = 0;
+// 		for($i = 0; $i < count ( $bytes ); $i ++) {
+// 			$val = bcadd($val, bcmul($bytes [$i], bcpow(256, count ( $bytes ) - 1 - $i)));
+// // 			echo $val . "<br>\n";
+// 		}
+// 		return $val;
+// 	}
+	
+// 	private static function toStr($bytes) {
+// 		$str = '';
+// 		foreach($bytes as $ch) {
+// 			$str .= chr($ch);
+// 		}
+// 		return $str;
+// 	}
+	
+// 	public static function getSerial($fileData, &$errMsg) {
+		
+// // 		$fileData = str_replace('\n','',$fileData);
+// // 		$fileData = str_replace('\r','',$fileData);
+		
+// 		$start = "-----BEGIN CERTIFICATE-----";
+// 		$end = "-----END CERTIFICATE-----";
+// 		$data = trim ( $fileData );
+// 		if (substr ( $data, 0, strlen ( $start ) ) != $start || 
+// 		substr ( $data, strlen ( $data ) - strlen ( $end ) ) != $end) {
+// 			// echo $fileData;
+// 			$errMsg = "error pem data";
+// 			return false;
+// 		}
+		
+// 		$data = substr ( $data, strlen ( $start ), strlen ( $data ) - strlen ( $end ) - strlen ( $start ) );
+// 		$bindata = base64_decode ( $data );
+// 		$bindata = unpack ( 'C*', $bindata );
+		
+// 		$byte = array_shift ( $bindata );
+// 		if ($byte != 0x30) {
+// 			$errMsg = "1st tag " . $byte . " is not 30"; 
+// 			return false;
+// 		}
+		
+// 		$length = CertSerialUtil::readLength ( $bindata ); 
+// 		$byte = array_shift ( $bindata );
+// 		if ($byte != 0x30) {
+// 			$errMsg = "2nd tag " . $byte . " is not 30";
+// 			return false;
+// 		}
+		
+// 		$length = CertSerialUtil::readLength ( $bindata );
+// 		$byte = array_shift ( $bindata );
+// // 		echo $byte . "<br>\n";
+// 		if ($byte == 0xa0) { //version tag.
+// 			$length = CertSerialUtil::readLength ( $bindata );
+// 			CertSerialUtil::readData ( $bindata, $length );
+// 			$byte = array_shift ( $bindata );
+// 		}
+
+// // 		echo $byte . "<br>\n";
+// 		if ($byte != 0x02) { //x509v1 has no version tag, x509v3 has.
+// 			$errMsg = "4th/3rd tag " . $byte . " is not 02";
+// 			return false;
+// 		}
+// 		$length = CertSerialUtil::readLength ( $bindata );
+// 		$serial = CertSerialUtil::readData ( $bindata, $length );
+// // 		echo bin2hex(CertSerialUtil::toStr( $serial ));
+// 		return CertSerialUtil::bytesToBigInteger($serial);
+// 	}
+	
+// 	private static function readLength(&$bindata) {
+// 		$byte = array_shift ( $bindata );
+// 		if ($byte < 0x80) {
+// 			$length = $byte;
+// 		} else {
+// 			$lenOfLength = $byte - 0x80;
+// 			for($i = 0; $i < $lenOfLength; $i ++) {
+// 				$lenBytes [] = array_shift ( $bindata );
+// 			}
+// 			$length = CertSerialUtil::bytesToInteger ( $lenBytes );
+// 		}
+// 		return $length;
+// 	}
+	
+// 	private static function readData(&$bindata, $length) {
+// 		$data = array ();
+// 		for($i = 0; $i < $length; $i ++) {
+// 			$data [] = array_shift ( $bindata );
+// 		}
+// 		return $data;
+// 	}
+// }
+
+
+
+
+
+    

+ 196 - 0
application/common/library/upacp_demo_b2c/sdk/common.php

@@ -0,0 +1,196 @@
+<?php
+namespace com\unionpay\acp\sdk;
+include_once 'log.class.php';
+include_once 'SDKConfig.php';
+header ( 'Content-type:text/html;charset=utf-8' );
+
+class LogUtil
+{
+	private static $_logger = null;
+	public static function getLogger()
+	{
+		if (LogUtil::$_logger == null ) {
+			$l = SDKConfig::getSDKConfig()->logLevel;
+			if("INFO" == strtoupper($l))
+				$level = PhpLog::INFO;
+			else if("DEBUG" == strtoupper($l))
+				$level = PhpLog::DEBUG;
+			else if("ERROR" == strtoupper($l))
+				$level = PhpLog::ERROR;
+			else if("WARN" == strtoupper($l))
+				$level = PhpLog::WARN;
+			else if("FATAL" == strtoupper($l))
+				$level = PhpLog::FATAL;
+			else
+				$level = PhpLog::OFF;
+			LogUtil::$_logger = new PhpLog ( SDKConfig::getSDKConfig()->logFilePath, "PRC", $level );
+		}
+		return self::$_logger;
+	}
+}
+
+/**
+ * key1=value1&key2=value2转array
+ * @param $str key1=value1&key2=value2的字符串
+ * @param $$needUrlDecode 是否需要解url编码,默认不需要
+ */
+function parseQString($str, $needUrlDecode=false){
+	$result = array();
+	$len = strlen($str);
+	$temp = "";
+	$curChar = "";
+	$key = "";
+	$isKey = true;
+	$isOpen = false;
+	$openName = "\0";
+
+	for($i=0; $i<$len; $i++){
+		$curChar = $str[$i];
+		if($isOpen){
+			if( $curChar == $openName){
+				$isOpen = false;
+			}
+			$temp .= $curChar;
+		} elseif ($curChar == "{"){
+			$isOpen = true;
+			$openName = "}";
+			$temp .= $curChar;
+		} elseif ($curChar == "["){
+			$isOpen = true;
+			$openName = "]";
+			$temp .= $curChar;
+		} elseif ($isKey && $curChar == "="){
+			$key = $temp;
+			$temp = "";
+			$isKey = false;
+		} elseif ( $curChar == "&" && !$isOpen){
+			putKeyValueToDictionary($temp, $isKey, $key, $result, $needUrlDecode);
+			$temp = "";
+			$isKey = true;
+		} else {
+			$temp .= $curChar;
+		}
+	}
+	putKeyValueToDictionary($temp, $isKey, $key, $result, $needUrlDecode);
+	return $result;
+}
+
+
+function putKeyValueToDictionary($temp, $isKey, $key, &$result, $needUrlDecode) {
+	if ($isKey) {
+		$key = $temp;
+		if (strlen ( $key ) == 0) {
+			return false;
+		}
+		$result [$key] = "";
+	} else {
+		if (strlen ( $key ) == 0) {
+			return false;
+		}
+		if ($needUrlDecode)
+			$result [$key] = urldecode ( $temp );
+		else
+			$result [$key] = $temp;
+	}
+}
+
+/**
+ * 取得备份文件名
+ * 
+ * Enter description here ...
+ * @param $path
+ */
+function getBackupFileName($path){
+	$i = strrpos($path, ".");
+	$leftFileName = substr($path, 0, $i);
+	$rightFileName = substr($path, $i + 1);
+	$newFileName = $leftFileName . '_backup.' . $rightFileName;
+	return $newFileName;
+}
+
+/**
+ * 字符串转换为 数组
+ *
+ * @param unknown_type $str
+ * @return multitype:unknown
+ */
+function convertStringToArray($str) {
+	return parseQString($str);
+}
+
+/**
+ * 压缩文件 对应java deflate
+ *
+ * @param unknown_type $params        	
+ */
+function deflate_file(&$params) {
+	$logger = LogUtil::getLogger();
+	foreach ( $_FILES as $file ) {
+		$logger->LogInfo ( "---------处理文件---------" );
+		if (file_exists ( $file ['tmp_name'] )) {
+			$params ['fileName'] = $file ['name'];
+			
+			$file_content = file_get_contents ( $file ['tmp_name'] );
+			$file_content_deflate = gzcompress ( $file_content );
+			
+			$params ['fileContent'] = base64_encode ( $file_content_deflate );
+			$logger->LogInfo ( "压缩后文件内容为>" . base64_encode ( $file_content_deflate ) );
+		} else {
+			$logger->LogInfo ( ">>>>文件上传失败<<<<<" );
+		}
+	}
+}
+
+
+/**
+ * 讲数组转换为string
+ *
+ * @param $para 数组        	
+ * @param $sort 是否需要排序        	
+ * @param $encode 是否需要URL编码        	
+ * @return string
+ */
+function createLinkString($para, $sort, $encode) {
+	if($para == NULL || !is_array($para))
+		return "";
+	
+	$linkString = "";
+	if ($sort) {
+		$para = argSort ( $para );
+	}
+	while ( list ( $key, $value ) = each ( $para ) ) {
+		if ($encode) {
+			$value = urlencode ( $value );
+		}
+		$linkString .= $key . "=" . $value . "&";
+	}
+	// 去掉最后一个&字符
+	$linkString = substr ( $linkString, 0, -1 );
+	
+	return $linkString;
+}
+
+/**
+ * 对数组排序
+ *
+ * @param $para 排序前的数组
+ *        	return 排序后的数组
+ */
+function argSort($para) {
+	ksort ( $para );
+	reset ( $para );
+	return $para;
+}
+
+
+function getProjName(){
+	$dir = str_replace("\\","/", dirname(__FILE__));
+	$rootDir = str_replace("\\", "/", $_SERVER ['DOCUMENT_ROOT']);
+	if($rootDir[strlen($rootDir) - 1] != "/") $rootDir = $rootDir . "/";
+	$index = strlen($rootDir);
+	$dir = substr($dir, $index);
+	$index = strpos($dir, "/");
+	$projName = substr($dir, 0, $index);
+	return $projName;
+}
+

+ 289 - 0
application/common/library/upacp_demo_b2c/sdk/log.class.php

@@ -0,0 +1,289 @@
+<?php 
+namespace com\unionpay\acp\sdk;
+
+	class PhpLog
+	{
+		const DEBUG = 1;// Most Verbose
+		const INFO = 2;// ...
+		const WARN = 3;// ...
+		const ERROR = 4;// ...
+		const FATAL = 5;// Least Verbose
+		const OFF = 6;// Nothing at all.
+		 
+		const LOG_OPEN = 1;
+		const OPEN_FAILED = 2;
+		const LOG_CLOSED = 3;
+		 
+		/* Public members: Not so much of an example of encapsulation, but that's okay. */
+		public $Log_Status = PhpLog::LOG_CLOSED;
+		public $DateFormat= "Y-m-d G:i:s";
+		public $MessageQueue;
+		 
+		private $filename;
+		private $log_file;
+		private $priority = PhpLog::INFO;
+		 
+		private $file_handle;
+		
+		/**
+		 * AUTHOR:	gu_yongkang
+		 * DATA:	20110322
+		 * Enter description here ...
+		 * @param $filepath
+		 * 文件存储的路径
+		 * @param $timezone
+		 * 时间格式,此处设置为"PRC"(中国)
+		 * @param $priority
+		 * 设置运行级别
+		 */
+		 
+		public function __construct( $filepath, $timezone, $priority )
+		{
+			if ( $priority == PhpLog::OFF ) return;
+			 
+			$this->filename = date('Y-m-d', time()) . '.log';	//默认为以时间+.log的文件文件
+			$this->log_file = $this->createPath($filepath, $this->filename);
+			$this->MessageQueue = array();
+			$this->priority = $priority;
+			date_default_timezone_set($timezone);
+			 
+			if ( !file_exists($filepath) )	//判断文件路径是否存在
+			{
+				if(!empty($filepath))	//判断路径是否为空
+				{
+					if(!($this->_createDir($filepath)))
+					{
+						$this->Log_Status = PhpLog::OPEN_FAILED;
+						$this->MessageQueue[] = "Create file failed.";
+						return;
+					}
+					if ( !is_writable($this->log_file) )
+					{
+						$this->Log_Status = PhpLog::OPEN_FAILED;
+						$this->MessageQueue[] = "The file exists, but could not be opened for writing. Check that appropriate permissions have been set.";
+						return;
+					}
+				}
+			}
+		 
+			if ( $this->file_handle = fopen( $this->log_file , "a+" ) )
+			{
+				$this->Log_Status = PhpLog::LOG_OPEN;
+				$this->MessageQueue[] = "The log file was opened successfully.";
+			}
+			else
+			{
+				$this->Log_Status = PhpLog::OPEN_FAILED;
+				$this->MessageQueue[] = "The file could not be opened. Check permissions.";
+			}
+			return;
+		}
+		 
+		public function __destruct()
+		{
+			if ( $this->file_handle )
+			fclose( $this->file_handle );
+		}
+		
+		/**
+	     *作用:创建目录
+	     *输入:要创建的目录
+	     *输出:true | false
+	     */
+		private  function _createDir($dir)
+		{
+		//	return is_dir($dir) or (self::_createDir(dirname($dir)) and mkdir($dir, 0777));
+			return false;
+		}
+		
+		/**
+	     *作用:构建路径
+	     *输入:文件的路径,要写入的文件名
+	     *输出:构建好的路径字串
+	     */
+		private function createPath($dir, $filename)
+		{
+			if (empty($dir)) 
+			{
+				return $filename;
+			} 
+			else 
+			{
+				return $dir . "/" . $filename;
+			}
+		}
+		 
+		public function LogInfo($line)
+		{
+			/**
+			 * AUTHOR : gu_yongkang
+			 * 增加打印函数和文件名的功能
+			 */
+			$sAarray = array();
+			$sAarray = debug_backtrace();
+			$sGetFilePath = $sAarray[0]["file"];
+			$sGetFileLine = $sAarray[0]["line"];
+			$this->Log( $line, PhpLog::INFO, $sGetFilePath, $sGetFileLine);
+			unset($sAarray);
+			unset($sGetFilePath);
+			unset($sGetFileLine);
+		}
+		 
+		public function LogDebug($line)
+		{
+			/**
+			 * AUTHOR : gu_yongkang
+			 * 增加打印函数和文件名的功能
+			 */
+			$sAarray = array();
+			$sAarray = debug_backtrace();
+			$sGetFilePath = $sAarray[0]["file"];
+			$sGetFileLine = $sAarray[0]["line"];
+			$this->Log( $line, PhpLog::DEBUG, $sGetFilePath, $sGetFileLine);
+			unset($sAarray);
+			unset($sGetFilePath);
+			unset($sGetFileLine);
+		}
+		 
+		public function LogWarn($line)
+		{
+			/**
+			 * AUTHOR : gu_yongkang
+			 * 增加打印函数和文件名的功能
+			 */
+			$sAarray = array();
+			$sAarray = debug_backtrace();
+			$sGetFilePath = $sAarray[0]["file"];
+			$sGetFileLine = $sAarray[0]["line"];
+			$this->Log( $line, PhpLog::WARN, $sGetFilePath, $sGetFileLine);
+			unset($sAarray);
+			unset($sGetFilePath);
+			unset($sGetFileLine);
+		}
+		 
+		public function LogError($line)
+		{
+			/**
+			 * AUTHOR : gu_yongkang
+			 * 增加打印函数和文件名的功能
+			 */
+			$sAarray = array();
+			$sAarray = debug_backtrace();
+			$sGetFilePath = $sAarray[0]["file"];
+			$sGetFileLine = $sAarray[0]["line"];
+			$this->Log( $line, PhpLog::ERROR, $sGetFilePath, $sGetFileLine);
+			unset($sAarray);
+			unset($sGetFilePath);
+			unset($sGetFileLine);
+		}
+		 
+		public function LogFatal($line)
+		{
+			/**
+			 * AUTHOR : gu_yongkang
+			 * 增加打印函数和文件名的功能
+			 */
+			$sAarray = array();
+			$sAarray = debug_backtrace();
+			$sGetFilePath = $sAarray[0]["file"];
+			$sGetFileLine = $sAarray[0]["line"];
+			$this->Log( $line, PhpLog::FATAL, $sGetFilePath, $sGetFileLine);
+			unset($sAarray);
+			unset($sGetFilePath);
+			unset($sGetFileLine);
+		}
+
+		/**
+		 * Author : gu_yongkang
+		 * Enter description here ...
+		 * @param unknown_type $line
+		 * content 内容
+		 * @param unknown_type $priority
+		 * 打印级别
+		 * @param unknown_type $sFile
+		 * 调用打印日志的文件名
+		 * @param unknown_type $iLine
+		 * 打印文件的位置(行数)
+		 */
+		public function Log($line, $priority, $sFile, $iLine)
+		{
+			if ($iLine > 0)
+			{
+				//$line = iconv('GBK', 'UTF-8', $line);
+				if ( $this->priority <= $priority )
+				{
+					$status = $this->getTimeLine( $priority, $sFile, $iLine);
+					$this->WriteFreeFormLine ( "$status $line \n" );
+				}
+			}
+			else 
+			{
+				/**
+				 * AUTHOR : gu_yongkang
+				 * 增加打印函数和文件名的功能
+				 */
+				$sAarray = array();
+				$sAarray = debug_backtrace();
+				$sGetFilePath = $sAarray[0]["file"];
+				$sGetFileLine = $sAarray[0]["line"];
+				if ( $this->priority <= $priority )
+				{
+					$status = $this->getTimeLine( $priority, $sGetFilePath, $sGetFileLine);
+					unset($sAarray);
+					unset($sGetFilePath);
+					unset($sGetFileLine);
+					$this->WriteFreeFormLine ( "$status $line \n" );
+				}
+			}
+		}
+		 // 支持输入多个参数
+		public function WriteFreeFormLine( $line )
+		{
+			if ( $this->Log_Status == PhpLog::LOG_OPEN && $this->priority != PhpLog::OFF )
+			{
+				if (fwrite( $this->file_handle , $line ) === false) 
+				{
+					$this->MessageQueue[] = "The file could not be written to. Check that appropriate permissions have been set.";
+				}
+			}
+		}
+		private function getRemoteIP()
+		{
+			foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key)
+			{
+				if (array_key_exists($key, $_SERVER) === true)
+				{
+					foreach (explode(',', $_SERVER[$key]) as $ip)
+					{
+						$ip = trim($ip);
+						if (!empty($ip))
+						{
+							return $ip;
+						}
+					}
+				}
+			}
+			return "_NO_IP";
+		}
+		 
+		private function getTimeLine( $level, $FilePath, $FileLine)
+		{			
+			$time = date( $this->DateFormat );
+			$ip = $this->getRemoteIP();
+			switch( $level )
+			{
+				case PhpLog::INFO:
+				return "$time, " . "INFO, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+				case PhpLog::WARN:
+				return "$time, " . "WARN, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+				case PhpLog::DEBUG:
+				return "$time, " . "DEBUG, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+				case PhpLog::ERROR:
+				return "$time, " . "ERROR, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+				case PhpLog::FATAL:
+				return "$time, " . "FATAL, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+				default:
+				return "$time, " . "LOG, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------";
+			}
+		}
+	}

+ 25 - 0
application/common/library/upacp_demo_b2c/static/demo.css

@@ -0,0 +1,25 @@
+@CHARSET "UTF-8";
+/*! index页面 */
+  .ui-tabs-vertical { width: 51.5em; }
+  .ui-tabs-vertical .ui-tabs-nav { padding: .2em .1em .2em .2em; float: left; width: 11em; }
+  .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 1px !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; }
+  .ui-tabs-vertical .ui-tabs-nav li a { display:block; }
+  .ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { padding-bottom: 0; padding-right: .1em; border-right-width: 1px; border-right-width: 1px; }
+  .ui-tabs-vertical .ui-tabs-panel { padding: 1.2em; float: right; width: 37.5em;}
+  .ui-tabs { font-family:微软雅黑; }
+  #header { width: inherit; height:3em; }
+  #wrapper{ font-family:微软雅黑;width:61em; margin:0 auto; font-size: 16px; color: #5E5E5E;}
+  h1,h2,h3,h4,h5,h6,h7,.ui-tooltip{font-family:微软雅黑 !important; color: #555 !important;}
+
+
+/*! 各个接口的页面 */
+  hr{height:1px;border:none;border-top:1px dashed #9DC45F;}
+  .api-form {  background: #F8F8F8;padding: 30px 30px 20px 30px; color: #666;border-radius: 5px;-webkit-border-radius: 5px;-moz-border-radius: 5px;}
+  .api-form p {display: block; margin: 0px 0px 5px; }
+  .api-form label {height:2em; vertical-align:middle;float: left; width: 10em; text-align: right; padding-right: 0.5em; margin-top: .1em; padding-top:.3em; color: #5E5E5E;}
+  .api-form input[type="text"] {border: 1px solid #E5E5E5;;color: #555;height: 20px;line-height:15px;margin-bottom: 10px;margin-right: 6px;margin-top: 2px;outline: 0 none;padding: 5px 0px 5px 5px;width: 65%;border-radius: 4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);}
+  .api-form input[type="submit"] {font-family:微软雅黑; background-color: #9DC45F;border-radius: 5px;-webkit-border-radius: 5px;-moz-border-border-radius: 5px;border: none;padding: 10px 25px 10px 25px;color: #FFF;text-shadow: 1px 1px 1px #949494;}
+  .api-form input[type="submit"]:hover {font-family:微软雅黑; background-color:#80A24A;}
+  .api-form .showFaqBtn{font-family:微软雅黑; float:right; background-color:transparent; color:inherit;border: none;padding: 10px 25px 10px 25px;}
+  .faq { font-size: 14px;font-weight: normal; }
+  .api-form select{ height: 34px;background-color:#FFFFFF;width: 9em;margin-bottom: 20px;margin-right: 6px;margin-top: 2px;outline: 0 none;padding: 5px 0px 5px 5px;border: 1px solid #ccc;-webkit-appearance: none; /*for chrome*/}

+ 20 - 0
application/common/library/upacp_demo_b2c/static/demo.js

@@ -0,0 +1,20 @@
+$(function() {
+	
+	  //index
+    $( "#tabs-api" ).tabs(); 
+    //form的title属性提示信息
+    $( document ).tooltip();
+	
+});
+  
+function setApiDemoTabs(selector){
+		  //beforeLoad是ajax应答失败的情况给个提示,load是html加载成功之后再加js,不然不会执行。
+		  //默认上边圆角,改为左边圆角
+	  $( selector ).tabs({ beforeLoad: function( event, ui ) { 
+    	ui.jqXHR.error(function() { ui.panel.html( "加载中" ); });
+    	}, load: function(event, ui){
+					 $( ".question" ).hide();
+				   $( ".showFaqBtn" ).click(
+				       function() {  $( ".question" ).toggle();   });}}).addClass( "ui-tabs-vertical ui-helper-clearfix" );
+    $( selector+" li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" ); 
+}

二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_diagonals-thick_20_666666_40x40.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_flat_10_000000_40x100.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_100_f6f6f6_1x400.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_100_fdf5ce_1x400.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_glass_65_ffffff_1x400.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-icons_222222_256x240.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-icons_228ef1_256x240.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-icons_ef8c08_256x240.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-icons_ffd27a_256x240.png


二進制
application/common/library/upacp_demo_b2c/static/images/ui-icons_ffffff_256x240.png


File diff suppressed because it is too large
+ 1 - 0
application/common/library/upacp_demo_b2c/static/jquery-1.11.2.min.js


File diff suppressed because it is too large
+ 6 - 0
application/common/library/upacp_demo_b2c/static/jquery-ui.min.css


File diff suppressed because it is too large
+ 5 - 0
application/common/library/upacp_demo_b2c/static/jquery-ui.min.js


+ 7 - 0
application/common/library/upacp_demo_b2c/static/subpage.js

@@ -0,0 +1,7 @@
+$(function() {
+    //各个接口的页面
+    $( document ).tooltip();
+	$( ".question" ).hide();
+    $( "div.question" ).hide();
+    $( ".showFaqBtn" ).click(function() {  $( ".question" ).toggle();   });
+  });

+ 2 - 4
application/common/library/upacp_demo_qrc/demo/api_16_qrc/Form_3_1_UnifiedOrder.php

@@ -26,20 +26,18 @@ $params = array(
 		'encoding' => 'utf-8',				  //编码方式
 		'txnType' => '01',				      //交易类型
 		'txnSubType' => '01',				  //交易子类
-		'bizType' => '000000',				  //业务类型
+		'bizType' => '000201',				  //业务类型
 		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl,	  //后台通知地址
 		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,	              //签名方法
-		'channelType' => '08',	              //渠道类型,07-PC,08-手机
+		'channelType' => '07',	              //渠道类型,07-PC,08-手机
 		'accessType' => '0',		          //接入类型
 		'currencyCode' => '156',	          //交易币种,境内商户固定156
 		'tradeType' => 'mobileWeb',	          //交易场景 固定填写	mobileWeb
-		
 		//TODO 以下信息需要填写
 		'merId' => $_POST["merId"],		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
 		'orderId' => $_POST["orderId"],	//商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
 		'txnTime' => $_POST["txnTime"],	//订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
 		'txnAmt' => $_POST["txnAmt"],	//交易金额,单位分,此处默认取demo演示页面传递的参数
-		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址	
 
 		// 请求方保留域,
 		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。

+ 4 - 2
application/common/library/upacp_demo_qrc/demo/api_16_qrc/Form_6_2_ApplyQrCode.php

@@ -34,11 +34,10 @@ $params = array(
 		'currencyCode' => '156',	          //交易币种,境内商户固定156
 		
 		//TODO 以下信息需要填写
-		'merId' => $_POST["merId"],		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+		'merId' => '777290058200548',		//商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
 		'orderId' => $_POST["orderId"],	//商户订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数,可以自行定制规则
 		'txnTime' => $_POST["txnTime"],	//订单发送时间,格式为YYYYMMDDhhmmss,取北京时间,此处默认取demo演示页面传递的参数
 		'txnAmt' => $_POST["txnAmt"],	//交易金额,单位分,此处默认取demo演示页面传递的参数
-		'backUrl' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl, //后台通知地址	
 
 		// 请求方保留域,
 		// 透传字段,查询、通知、对账文件中均会原样出现,如有需要请启用并修改自己希望透传的数据。
@@ -59,6 +58,9 @@ com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
 $url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backTransUrl;
 
 $result_arr = com\unionpay\acp\sdk\AcpService::post ($params,$url);
+echo '<pre>';
+print_r($result_arr);
+die;
 if(count($result_arr)<=0) { //没收到200应答的情况
 	printResult ($url, $params, "" );
 	return;

+ 0 - 6
application/common/library/upacp_demo_qrc/index_16_qrc.php

@@ -46,15 +46,9 @@
 
 <div id="tabs-api">
   <ul>
-    <li><a href="#tabs-api-1">前言</a></li>
     <li><a href="#tabs-api-2">交易样例</a></li>
     <li><a href="#tabs-api-4">常见开发问题</a></li>
   </ul>
-  
-  <div id="tabs-api-1">
-    <?php include 'pages/api_16_qrc/introduction.php';?>
-  </div>
-  
   <div id="tabs-api-4">
     <?php include 'pages/dev_faq.php';?>
   </div>

+ 1 - 1
application/common/library/upacp_demo_qrc/sdk/SDKConfig.php

@@ -4,7 +4,7 @@ include_once 'log.class.php';
 include_once 'common.php';
 
 class SDKConfig {
-	
+	/** @var SDKConfig */
 	private static $_config = null;
 	public static function getSDKConfig(){
 		if (SDKConfig::$_config == null ) {

Some files were not shown because too many files changed in this diff