move module.local to module
2
modules/ppcp-wc-gateway/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
vendor
|
||||
build
|
37
modules/ppcp-wc-gateway/assets/images/amex.svg
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="1000" height="997.51703" id="svg2" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="American_Express_2018.svg">
|
||||
<defs id="defs4"/>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.125" inkscape:cx="850.2929" inkscape:cy="357.59411" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1680" inkscape:window-height="931" inkscape:window-x="0" inkscape:window-y="1" inkscape:window-maximized="1">
|
||||
<inkscape:grid type="xygrid" id="grid2996" empspacing="5" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="-55.5px" originy="947.50002px"/>
|
||||
</sodipodi:namedview>
|
||||
<metadata id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-55.5,-1002.3452)">
|
||||
<path sodipodi:nodetypes="ccccccccccc" inkscape:connector-curvature="0" id="path3078" d="m 55.5,1002.3454 997.5168,0 0,538.4893 -49.3744,77.1475 49.3744,68.6613 0,313.2187 -997.5168,0 0,-507.6304 L 86.358989,1456.744 55.5,1422.7991 Z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path sodipodi:nodetypes="cccccccccccccccccccc" inkscape:connector-curvature="0" id="path3082" d="m 249.14015,1697.4441 0,-156.6094 165.82027,0 17.79072,23.1924 18.37901,-23.1924 601.88665,0 0,145.8088 c 0,0 -15.7404,10.644 -33.9449,10.8006 l -333.27706,0 -20.05834,-24.6872 0,24.6872 -65.72965,0 0,-42.1418 c 0,0 -8.97877,5.8825 -28.39026,5.8825 l -22.37277,0 0,36.2593 -99.52024,0 -17.7653,-23.6898 -18.03807,23.6898 z" style="fill:#ffffff;stroke:none"/>
|
||||
<path sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccc" inkscape:connector-curvature="0" id="path3080" d="m 55.5,1422.7991 37.393125,-87.1766 64.667505,0 21.22103,48.8328 0,-48.8328 80.38767,0 12.63289,35.2949 12.24716,-35.2949 360.8573,0 0,17.7439 c 0,0 18.96995,-17.7439 50.14586,-17.7439 l 117.08499,0.4092 20.85469,48.1937 0,-48.6029 67.27259,0 18.5154,27.6834 0,-27.6834 67.88977,0 0,156.6093 -67.88977,0 -17.74392,-27.7731 0,27.7731 -98.83835,0 -9.93959,-24.6872 -26.57108,0 -9.77781,24.6872 -67.02872,0 c -26.82589,0 -43.97406,-17.3816 -43.97406,-17.3816 l 0,17.3816 -101.06318,0 -20.05835,-24.6872 0,24.6872 -375.80462,0 -9.93274,-24.6872 -26.48635,0 -9.86254,24.6872 -46.1989,0 z" style="fill:#ffffff;stroke:none"/>
|
||||
<path id="path3046" d="m 106.12803,1354.9291 -50.435161,117.2641 32.835892,0 9.305914,-23.4816 54.099665,0 9.2577,23.4816 33.55915,0 -50.38695,-117.2641 -38.23621,0 z m 18.66004,27.2909 16.49028,41.0329 -33.02877,0 16.53849,-41.0329 z" style="fill:#016fd0;fill-opacity:1;stroke:none" inkscape:connector-curvature="0"/>
|
||||
<path sodipodi:nodetypes="cccccccccccccc" inkscape:connector-curvature="0" id="path3048" d="m 198.22282,1472.1735 0,-117.2642 46.66163,0.1733 27.13999,75.6045 26.4901,-75.7778 46.28848,0 0,117.2642 -29.31604,0 0,-86.4052 -31.07562,86.4052 -25.71023,0 -31.16227,-86.4052 0,86.4052 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="path3050" d="m 364.86136,1472.1735 0,-117.2642 95.66287,0 0,26.2302 -66.03824,0 0,20.0583 64.49529,0 0,24.6872 -64.49529,0 0,20.8298 66.03824,0 0,25.4587 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path id="path3052" d="m 477.49667,1354.9291 0,117.2641 29.31604,0 0,-41.6596 12.34359,0 35.15032,41.6596 35.82536,0 -38.57374,-43.2025 c 15.8309,-1.3359 32.16085,-14.9233 32.16085,-36.0182 0,-24.6765 -19.36827,-38.0434 -40.98459,-38.0434 l -65.23783,0 z m 29.31604,26.2301 33.51093,0 c 8.03881,0 13.88655,6.2882 13.88655,12.3436 0,7.7905 -7.57673,12.3436 -13.45259,12.3436 l -33.94489,0 0,-24.6872 z" style="fill:#016fd0;fill-opacity:1;stroke:none" inkscape:connector-curvature="0"/>
|
||||
<path sodipodi:nodetypes="ccccc" inkscape:connector-curvature="0" id="path3054" d="m 625.61982,1472.1735 -29.93322,0 0,-117.2642 29.93322,0 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccccccccc" inkscape:connector-curvature="0" id="path3056" d="m 696.59549,1472.1735 -6.4611,0 c -31.26172,0 -50.24229,-24.6292 -50.24229,-58.1499 0,-34.3488 18.76806,-59.1143 58.24634,-59.1143 l 32.40194,0 0,27.7731 -33.58657,0 c -16.026,0 -27.35994,12.5067 -27.35994,31.6305 0,22.7096 12.95987,32.2476 31.63047,32.2476 l 7.71474,0 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path inkscape:connector-curvature="0" style="fill:#016fd0;fill-opacity:1;stroke:none" d="m 760.3868,1354.9291 -50.43515,117.2641 32.83589,0 9.30591,-23.4816 54.09967,0 9.25769,23.4816 33.55915,0 -50.38694,-117.2641 -38.23622,0 z m 18.66005,27.2909 16.49027,41.0329 -33.02876,0 16.53849,-41.0329 z" id="path3058"/>
|
||||
<path sodipodi:nodetypes="ccccccccccc" inkscape:connector-curvature="0" id="path3060" d="m 852.43338,1472.1735 0,-117.2642 37.27187,0 47.59035,73.6759 0,-73.6759 29.31604,0 0,117.2642 -36.06644,0 -48.79578,-75.6045 0,75.6045 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path style="fill:#016fd0;fill-opacity:1;stroke:none" d="m 269.1985,1677.3858 0,-117.2642 95.66286,0 0,26.2302 -66.03823,0 0,20.0583 64.49528,0 0,24.6872 -64.49528,0 0,20.8298 66.03823,0 0,25.4587 z" id="path3062" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccc"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="path3064" d="m 737.94653,1677.3858 0,-117.2642 95.66287,0 0,26.2302 -66.03824,0 0,20.0583 64.1867,0 0,24.6872 -64.1867,0 0,20.8298 66.03824,0 0,25.4587 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="path3066" d="m 368.57408,1677.3858 46.57779,-57.9089 -47.68678,-59.3553 36.93435,0 28.39991,36.6932 28.49635,-36.6932 35.48784,0 -47.05996,58.6321 46.66353,58.6321 -36.92851,0 -27.57537,-36.1148 -26.90518,36.1148 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path style="fill:#016fd0;fill-opacity:1;stroke:none" d="m 499.86944,1560.1414 0,117.2641 30.08751,0 0,-37.0308 30.85899,0 c 26.11107,0 45.90274,-13.8524 45.90274,-40.7917 0,-22.3164 -15.52271,-39.4416 -42.09358,-39.4416 l -64.75566,0 z m 30.08751,26.5194 32.49837,0 c 8.43546,0 14.46515,5.1701 14.46515,13.5008 0,7.8262 -5.99925,13.5008 -14.56158,13.5008 l -32.40194,0 0,-27.0016 z" id="path3068" inkscape:connector-curvature="0"/>
|
||||
<path inkscape:connector-curvature="0" style="fill:#016fd0;fill-opacity:1;stroke:none" d="m 619.44802,1560.1216 0,117.2642 29.31604,0 0,-41.6597 12.34359,0 35.15032,41.6597 35.82536,0 -38.57374,-43.2026 c 15.83089,-1.3361 32.16085,-14.9233 32.16085,-36.0183 0,-24.6764 -19.36827,-38.0433 -40.98459,-38.0433 l -65.23783,0 z m 29.31604,26.2302 33.51093,0 c 8.03881,0 13.88654,6.2881 13.88654,12.3435 0,7.7906 -7.57673,12.3436 -13.45259,12.3436 l -33.94488,0 0,-24.6871 z" id="path3072"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccccccc" inkscape:connector-curvature="0" id="path3074" d="m 847.18735,1677.3858 0,-25.4587 58.67066,0 c 8.68115,0 12.44003,-4.6912 12.44003,-9.8363 0,-4.9296 -3.74703,-9.9134 -12.44003,-9.9134 l -26.5126,0 c -23.04571,0 -35.88042,-14.0409 -35.88042,-35.1214 0,-18.8023 11.75348,-36.9344 45.99918,-36.9344 l 57.08913,0 -12.3436,26.3844 -49.37438,0 c -9.43821,0 -12.3436,4.9526 -12.3436,9.6821 0,4.8612 3.59036,10.222 10.80065,10.222 l 27.77309,0 c 25.69029,0 36.83792,14.5724 36.83792,33.6556 0,20.5163 -12.42212,37.3201 -38.23646,37.3201 z" style="fill:#016fd0;fill-opacity:1;stroke:none"/>
|
||||
<path style="fill:#016fd0;fill-opacity:1;stroke:none" d="m 954.78398,1677.3858 0,-25.4587 58.67062,0 c 8.6812,0 12.4401,-4.6912 12.4401,-9.8363 0,-4.9296 -3.7471,-9.9134 -12.4401,-9.9134 l -26.51256,0 c -23.04571,0 -35.88043,-14.0409 -35.88043,-35.1214 0,-18.8023 11.75348,-36.9344 45.99918,-36.9344 l 57.08911,0 -12.3436,26.3844 -49.37436,0 c -9.4382,0 -12.34359,4.9526 -12.34359,9.6821 0,4.8612 3.59035,10.222 10.80064,10.222 l 27.77311,0 c 25.6903,0 36.8379,14.5724 36.8379,33.6556 0,20.5163 -12.4221,37.3201 -38.2365,37.3201 z" id="path3076" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccccccc"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
26
modules/ppcp-wc-gateway/assets/images/discover.svg
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg:svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="304mm" height="64mm" id="svg3187" version="1.1" inkscape:version="0.47 r22583" sodipodi:docname="orange.svg">
|
||||
<svg:metadata id="metadata2899">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</svg:metadata>
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="666" inkscape:window-height="483" id="namedview2897" showgrid="false" inkscape:zoom="0.50800003" inkscape:cx="557.47396" inkscape:cy="95.669289" inkscape:window-x="320" inkscape:window-y="342" inkscape:window-maximized="0" inkscape:current-layer="svg3187"/>
|
||||
<text x="0" y="0">Disc</text>
|
||||
<svg:defs id="defs3">
|
||||
<inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 95.669289 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="1062.9921 : 95.669289 : 1" inkscape:persp3d-origin="531.49603 : 63.779526 : 1" id="perspective2901"/>
|
||||
<svg:radialGradient cx="121.25" cy="97.588577" r="77.916664" fx="141.25" fy="77.588577" id="radialGradient3202" gradientUnits="userSpaceOnUse">
|
||||
<svg:stop stop-color="#f0f0f0" offset="0" id="stop2891"/>
|
||||
<svg:stop stop-color="#ff8330" offset="1" id="stop2893"/>
|
||||
</svg:radialGradient>
|
||||
</svg:defs>
|
||||
<svg:g id="layer1" transform="matrix(0.94947156,0,0,0.949483,496.94722,38.627248)">
|
||||
<svg:path d="m 199.16666,97.588577 a 77.916664,77.916664 0 1 1 -155.833324,0 77.916664,77.916664 0 1 1 155.833324,0 z" transform="translate(-25.8333,3.33333)" id="path3194" style="fill:url(#radialGradient3202)"/>
|
||||
</svg:g>
|
||||
<svg:text xml:space="preserve" style="font-size:220px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Verdana;-inkscape-font-specification:Verdana Bold" x="-9.8425188" y="193.30708" id="text2903" sodipodi:linespacing="125%"><svg:tspan sodipodi:role="line" id="tspan2905" x="-9.8425188" y="193.30708">Disc</svg:tspan></svg:text>
|
||||
<svg:text xml:space="preserve" style="font-size:220px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Verdana;-inkscape-font-specification:Verdana Bold" x="655.51172" y="193.41451" id="text2911" sodipodi:linespacing="125%"><svg:tspan sodipodi:role="line" id="tspan2913" x="655.51172" y="193.41451">ver</svg:tspan></svg:text>
|
||||
<svg:text xml:space="preserve" style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" x="1043.307" y="69.291351" id="text2820"><svg:tspan sodipodi:role="line" id="tspan2822" x="1043.307" y="69.291351">®</svg:tspan></svg:text>
|
||||
</svg:svg>
|
After Width: | Height: | Size: 3.3 KiB |
1
modules/ppcp-wc-gateway/assets/images/elo.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="780" height="500" enable-background="new 0 0 780 500" version="1.1" viewBox="0 0 780 500" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect width="780" height="500" fill="#000"/><path d="m167.25 181.4c6.8-2.3 14.1-3.5 21.7-3.5 33.2 0 60.9 23.601 67.2 54.9l47-9.6c-10.8-53.2-57.8-93.301-114.2-93.301-12.9 0-25.3 2.101-36.9 6l15.2 45.501z" fill="#FFF100"/><path d="m111.75 333.8l31.8-36c-14.2-12.6-23.1-30.9-23.1-51.4 0-20.399 8.9-38.8 23.1-51.3l-31.8-35.899c-24.1 21.399-39.3 52.5-39.3 87.3 0 34.699 15.2 65.898 39.3 87.299z" fill="#00A3DF"/><path d="m256.15 260.2c-6.4 31.3-34 54.8-67.2 54.8-7.6 0-14.9-1.2-21.8-3.5l-15.2 45.5c11.6 3.899 24.1 6 37 6 56.4 0 103.4-40 114.2-93.2l-47-9.6z" fill="#EE4023"/><path d="m459.75 292.4c-7.8 7.601-18.3 12.2-29.9 12-8-0.1-15.399-2.5-21.6-6.5l-15.601 24.801c10.7 6.699 23.2 10.699 36.801 10.899 19.699 0.3 37.699-7.5 50.8-20.2l-20.5-21zm-28.2-101.1c-39.2-0.6-71.6 30.8-72.2 70-0.2 14.7 4 28.5 11.5 39.9l128.8-55.101c-7.2-30.899-34.8-54.2-68.1-54.799m-42.7 75.599c-0.2-1.6-0.3-3.3-0.3-5 0.4-23.1 19.4-41.6 42.5-41.199 12.6 0.199 23.8 5.899 31.3 14.899l-73.5 31.3zm151.3-107.6v137.3l23.801 9.9-11.301 27.1-23.6-9.8c-5.3-2.3-8.9-5.8-11.6-9.8-2.601-4-4.601-9.601-4.601-17v-137.7h27.301zm85.901 63.5c4.2-1.4 8.6-2.1 13.3-2.1 20.3 0 37.101 14.399 41 33.5l28.7-5.9c-6.6-32.5-35.3-56.9-69.7-56.9-7.899 0-15.5 1.301-22.5 3.601l9.2 27.799zm-33.901 92.9l19.4-21.9c-8.7-7.7-14.1-18.9-14.1-31.4s5.5-23.699 14.1-31.3l-19.4-21.899c-14.699 13-24 32.1-24 53.3s9.301 40.199 24 53.199zm88.201-44.801c-3.899 19.101-20.8 33.5-41 33.5-4.6 0-9.1-0.8-13.3-2.199l-9.3 27.8c7.1 2.399 14.7 3.7 22.6 3.7 34.4 0 63.101-24.4 69.7-56.9l-28.7-5.901z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
18
modules/ppcp-wc-gateway/assets/images/hiper.svg
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 780 500" style="enable-background:new 0 0 780 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#F37421;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFE700;}
|
||||
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
</style>
|
||||
<rect y="0" class="st0" width="780" height="500"/>
|
||||
<g>
|
||||
<polygon class="st1" points="101,140.9 101,315.9 140.7,315.9 140.7,242.7 205.9,242.7 205.9,315.9 245.4,315.9 245.4,140.9 205.9,140.9 205.9,208.2 140.7,208.2 140.7,140.9 101,140.9 "/>
|
||||
<path class="st1" d="M587.2,265c0.5-2.9,1.3-8.8,1.3-15.6c0-31.4-15.6-63.4-56.6-63.4c-44.1,0-64.1,35.6-64.1,67.8 c0,39.7,24.7,64.7,67.8,64.7c17.1,0,33-2.6,46-7.8l-5.2-26.7c-10.6,3.4-21.6,5.2-35.1,5.2c-18.4,0-34.5-7.8-35.8-24.1H587.2 L587.2,265z M505.1,238c1-10.6,7.8-25.7,24.4-25.7c18.2,0,22.3,16.1,22.3,25.7H505.1L505.1,238z"/>
|
||||
<path class="st1" d="M601.1,315.9h39.5v-64.4c0-3.1,0.3-6.2,0.8-8.8c2.6-12.2,12.5-20,27-20c4.4,0,7.8,0.5,10.6,1v-37.1 c-2.9-0.5-4.7-0.5-8.3-0.5c-12.2,0-27.8,7.8-34.3,26.2h-1l-1.3-23.4h-34c0.5,10.9,1,23.1,1,41.8V315.9L601.1,315.9z"/>
|
||||
<path class="st2" d="M285.5,133.9c11.2,0,20.3,9.1,20.3,20.3c0,11.2-9.1,20.3-20.3,20.3c-11.2,0-20.3-9.1-20.3-20.3 C265.2,143,274.3,133.9,285.5,133.9L285.5,133.9z"/>
|
||||
<path class="st3" d="M368.9,286.3h19.8c19.9,0,28.9-12.7,28.9-26c0-13.3-1-43.3-25.5-43.3c-28.2,0-23.7,37.3-23.5,56.8 C368.5,278,368.8,282.2,368.9,286.3L368.9,286.3z M265.2,188.8h40.6v71.6c0,13.3,7.4,26,23.7,26c0.1-32.2,0-65.4-1.1-97.6h33.9 c0.7,6.2,1.4,12.4,2,18.6c16-32,66.5-25,83.5,2.1c17.5,27.9,23.5,107.9-59.1,107.9h-19.2c0.2,16.2,0.2,32.5,0.2,48.8h-40.6 c0-15.6,0.1-32,0.2-48.8c-43.9-0.2-64.1-28-64.1-57V188.8L265.2,188.8z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
9
modules/ppcp-wc-gateway/assets/images/jcb.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" height="231.511" width="300" xml:space="preserve" viewBox="0 0 300.00001 231.511" y="0px" x="0px" id="レイヤー_1" version="1.1"><metadata id="metadata6424"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs6422"/><style id="style6319" type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:url(#SVGID_1_);}
|
||||
.st2{fill:url(#SVGID_2_);}
|
||||
.st3{fill:url(#SVGID_3_);}
|
||||
.st4{fill:url(#SVGID_4_);}
|
||||
.st5{fill:url(#SVGID_5_);}
|
||||
</style><g transform="translate(-9.4000001,96.810998)" id="g6321"><g transform="matrix(1.8215159,0,0,1.8215159,-8.5437653,-109.83667)" id="g6323"><path style="fill:#ffffff" id="path6325" d="m 174,108.3 c 0,14 -11.4,25.4 -25.4,25.4 l -138.2,0 0,-100.6 c 0,-14 11.4,-25.4 25.4,-25.4 l 138.2,0 0,100.6 z" class="st0"/><g id="g6327"><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="81.398598" x2="157.3299" y1="81.398598" x1="117.3856" gradientUnits="userSpaceOnUse" id="SVGID_1_"><stop id="stop6330" style="stop-color:#007940" offset="0"/><stop id="stop6332" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6334" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6336" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_1_)" id="path6338" d="m 129,82.5 10.5,0 c 0.3,0 1,-0.1 1.3,-0.1 2,-0.4 3.7,-2.2 3.7,-4.7 0,-2.4 -1.7,-4.2 -3.7,-4.7 -0.3,-0.1 -0.9,-0.1 -1.3,-0.1 l -10.5,0 0,9.6 z" class="st1"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="157.3318" y1="75.171402" x1="117.3844" gradientUnits="userSpaceOnUse" id="SVGID_2_"><stop id="stop6341" style="stop-color:#007940" offset="0"/><stop id="stop6343" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6345" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6347" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_2_)" id="path6349" d="m 138.3,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,18.9 25.7,0 c 0.6,0 1.3,0 1.8,0.1 5.8,0.3 10.1,3.3 10.1,8.5 0,4.1 -2.9,7.6 -8.3,8.3 l 0,0.2 c 5.9,0.4 10.4,3.7 10.4,8.8 0,5.5 -5,9.1 -11.6,9.1 l -28.2,0 0,37 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.9 -26.6,0 z" class="st2"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="68.399101" x2="157.33051" y1="68.399101" x1="117.3846" gradientUnits="userSpaceOnUse" id="SVGID_3_"><stop id="stop6352" style="stop-color:#007940" offset="0"/><stop id="stop6354" style="stop-color:#00873F" offset="0.2285"/><stop id="stop6356" style="stop-color:#40A737" offset="0.7433"/><stop id="stop6358" style="stop-color:#5CB531" offset="1"/></linearGradient><path style="fill:url(#SVGID_3_)" id="path6360" d="m 143.2,63.1 c 0,-2.4 -1.7,-4 -3.7,-4.3 -0.2,0 -0.7,-0.1 -1,-0.1 l -9.5,0 0,8.8 9.5,0 c 0.3,0 0.9,0 1,-0.1 2,-0.3 3.7,-1.9 3.7,-4.3 z" class="st3"/></g><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="68.522102" y1="75.171402" x1="27.9594" gradientUnits="userSpaceOnUse" id="SVGID_4_"><stop id="stop6363" style="stop-color:#1F286F" offset="0"/><stop id="stop6365" style="stop-color:#004E94" offset="0.4751"/><stop id="stop6367" style="stop-color:#0066B1" offset="0.8261"/><stop id="stop6369" style="stop-color:#006FBC" offset="1"/></linearGradient><path style="fill:url(#SVGID_4_)" id="path6371" d="m 37.7,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,44.9 c 5.1,2.5 10.4,4.1 15.7,4.1 6.3,0 9.7,-3.8 9.7,-9 l 0,-21.2 15.6,0 0,21.1 c 0,8.2 -5.1,14.9 -22.4,14.9 -10.5,0 -18.7,-2.3 -18.7,-2.3 l 0,38.3 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.8 -26.6,0 z" class="st4"/><linearGradient gradientTransform="matrix(1.125,0,0,1.125,-11.9755,-13.8615)" y2="75.171402" x2="111.8553" y1="75.171402" x1="72.459503" gradientUnits="userSpaceOnUse" id="SVGID_5_"><stop id="stop6374" style="stop-color:#6C2C2F" offset="0"/><stop id="stop6376" style="stop-color:#882730" offset="0.1735"/><stop id="stop6378" style="stop-color:#BE1833" offset="0.5731"/><stop id="stop6380" style="stop-color:#DC0436" offset="0.8585"/><stop id="stop6382" style="stop-color:#E60039" offset="1"/></linearGradient><path style="fill:url(#SVGID_5_)" id="path6384" d="m 88,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,23.8 c 4.6,-3.9 12.6,-6.4 25.5,-5.8 6.9,0.3 14.3,2.2 14.3,2.2 l 0,7.7 c -3.7,-1.9 -8.1,-3.6 -13.8,-4 -9.8,-0.7 -15.7,4.1 -15.7,12.5 0,8.5 5.9,13.3 15.7,12.5 5.7,-0.4 10.1,-2.2 13.8,-4 l 0,7.7 c 0,0 -7.3,1.9 -14.3,2.2 -12.9,0.6 -20.9,-1.9 -25.5,-5.8 l 0,42 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-91 -26.7,0 z" class="st5"/></g><g id="g6386"/></g></svg>
|
After Width: | Height: | Size: 4.8 KiB |
26
modules/ppcp-wc-gateway/assets/images/mastercard.svg
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg3409" viewBox="0 0 1000.008 775.97201" height="775.97198" width="1000.008" inkscape:version="0.91 r13725" sodipodi:docname="MasterCard 2016.svg">
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1366" inkscape:window-height="705" id="namedview4178" showgrid="false" inkscape:zoom="0.35355339" inkscape:cx="400.80964" inkscape:cy="270.06961" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="svg3409"/>
|
||||
<defs id="defs3411"/>
|
||||
<metadata id="metadata3414">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="matrix(3.3557321,0,0,3.3557321,-1551.7864,-1849.1059)" id="layer1">
|
||||
<g transform="matrix(2.5579399,0,0,2.5579399,884.90115,-11.427398)" id="g13">
|
||||
<g transform="translate(-502.86126,-41.013507)" id="g15">
|
||||
<path d="m 358.9,351.1 0,-6 c 0,-2.3 -1.4,-3.8 -3.8,-3.8 -1.2,0 -2.5,0.4 -3.4,1.7 -0.7,-1.1 -1.7,-1.7 -3.2,-1.7 -1,0 -2,0.3 -2.8,1.4 l 0,-1.2 -2.1,0 0,9.6 2.1,0 0,-5.3 c 0,-1.7 0.9,-2.5 2.3,-2.5 1.4,0 2.1,0.9 2.1,2.5 l 0,5.3 2.1,0 0,-5.3 c 0,-1.7 1,-2.5 2.3,-2.5 1.4,0 2.1,0.9 2.1,2.5 l 0,5.3 2.3,0 z m 31.1,-9.6 -3.4,0 0,-2.9 -2.1,0 0,2.9 -1.9,0 0,1.9 1.9,0 0,4.4 c 0,2.2 0.9,3.5 3.3,3.5 0.9,0 1.9,-0.3 2.6,-0.7 l -0.6,-1.8 c -0.6,0.4 -1.3,0.5 -1.8,0.5 -1,0 -1.4,-0.6 -1.4,-1.6 l 0,-4.3 3.4,0 0,-1.9 z m 17.8,-0.2 c -1.2,0 -2,0.6 -2.5,1.4 l 0,-1.2 -2.1,0 0,9.6 2.1,0 0,-5.4 c 0,-1.6 0.7,-2.5 2,-2.5 0.4,0 0.9,0.1 1.3,0.2 l 0.6,-2 c -0.4,-0.1 -1,-0.1 -1.4,-0.1 l 0,0 z m -26.9,1 c -1,-0.7 -2.4,-1 -3.9,-1 -2.4,0 -4,1.2 -4,3.1 0,1.6 1.2,2.5 3.3,2.8 l 1,0.1 c 1.1,0.2 1.7,0.5 1.7,1 0,0.7 -0.8,1.2 -2.2,1.2 -1.4,0 -2.5,-0.5 -3.2,-1 l -1,1.6 c 1.1,0.8 2.6,1.2 4.1,1.2 2.8,0 4.4,-1.3 4.4,-3.1 0,-1.7 -1.3,-2.6 -3.3,-2.9 l -1,-0.1 c -0.9,-0.1 -1.6,-0.3 -1.6,-0.9 0,-0.7 0.7,-1.1 1.8,-1.1 1.2,0 2.4,0.5 3,0.8 l 0.9,-1.7 z m 55.8,-1 c -1.2,0 -2,0.6 -2.5,1.4 l 0,-1.2 -2.1,0 0,9.6 2.1,0 0,-5.4 c 0,-1.6 0.7,-2.5 2,-2.5 0.4,0 0.9,0.1 1.3,0.2 l 0.6,-2 c -0.4,-0.1 -1,-0.1 -1.4,-0.1 l 0,0 z m -26.8,5 c 0,2.9 2,5 5.1,5 1.4,0 2.4,-0.3 3.4,-1.1 l -1,-1.7 c -0.8,0.6 -1.6,0.9 -2.5,0.9 -1.7,0 -2.9,-1.2 -2.9,-3.1 0,-1.8 1.2,-3 2.9,-3.1 0.9,0 1.7,0.3 2.5,0.9 l 1,-1.7 c -1,-0.8 -2,-1.1 -3.4,-1.1 -3.1,0 -5.1,2.1 -5.1,5 l 0,0 z m 19.4,0 0,-4.8 -2.1,0 0,1.2 c -0.7,-0.9 -1.7,-1.4 -3,-1.4 -2.7,0 -4.8,2.1 -4.8,5 0,2.9 2.1,5 4.8,5 1.4,0 2.4,-0.5 3,-1.4 l 0,1.2 2.1,0 0,-4.8 z m -7.7,0 c 0,-1.7 1.1,-3.1 2.9,-3.1 1.7,0 2.9,1.3 2.9,3.1 0,1.7 -1.2,3.1 -2.9,3.1 -1.8,-0.1 -2.9,-1.4 -2.9,-3.1 l 0,0 z m -25.1,-5 c -2.8,0 -4.8,2 -4.8,5 0,3 2,5 4.9,5 1.4,0 2.8,-0.4 3.9,-1.3 l -1,-1.5 c -0.8,0.6 -1.8,1 -2.8,1 -1.3,0 -2.6,-0.6 -2.9,-2.3 l 7.1,0 c 0,-0.3 0,-0.5 0,-0.8 0.1,-3.1 -1.7,-5.1 -4.4,-5.1 l 0,0 z m 0,1.8 c 1.3,0 2.2,0.8 2.4,2.3 l -5,0 c 0.2,-1.3 1.1,-2.3 2.6,-2.3 l 0,0 z m 52.1,3.2 0,-8.6 -2.1,0 0,5 c -0.7,-0.9 -1.7,-1.4 -3,-1.4 -2.7,0 -4.8,2.1 -4.8,5 0,2.9 2.1,5 4.8,5 1.4,0 2.4,-0.5 3,-1.4 l 0,1.2 2.1,0 0,-4.8 z m -7.7,0 c 0,-1.7 1.1,-3.1 2.9,-3.1 1.7,0 2.9,1.3 2.9,3.1 0,1.7 -1.2,3.1 -2.9,3.1 -1.8,-0.1 -2.9,-1.4 -2.9,-3.1 l 0,0 z m -70.2,0 0,-4.8 -2.1,0 0,1.2 c -0.7,-0.9 -1.7,-1.4 -3,-1.4 -2.7,0 -4.8,2.1 -4.8,5 0,2.9 2.1,5 4.8,5 1.4,0 2.4,-0.5 3,-1.4 l 0,1.2 2.1,0 0,-4.8 z m -7.8,0 c 0,-1.7 1.1,-3.1 2.9,-3.1 1.7,0 2.9,1.3 2.9,3.1 0,1.7 -1.2,3.1 -2.9,3.1 -1.8,-0.1 -2.9,-1.4 -2.9,-3.1 z" id="XMLID_1775_" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
<g transform="translate(-502.86126,-41.013507)" id="XMLID_328_">
|
||||
<rect style="fill:#ff5f00" id="rect19" height="56.599998" width="31.5" class="st1" y="268.60001" x="380.20001"/>
|
||||
<path style="fill:#eb001b" d="m 382.2,296.9 c 0,-11.5 5.4,-21.7 13.7,-28.3 -6.1,-4.8 -13.8,-7.7 -22.2,-7.7 -19.9,0 -36,16.1 -36,36 0,19.9 16.1,36 36,36 8.4,0 16.1,-2.9 22.2,-7.7 -8.3,-6.5 -13.7,-16.8 -13.7,-28.3 z" class="st2" id="XMLID_330_" inkscape:connector-curvature="0"/>
|
||||
<path style="fill:#f79e1b" id="path22" d="m 454.2,296.9 c 0,19.9 -16.1,36 -36,36 -8.4,0 -16.1,-2.9 -22.2,-7.7 8.4,-6.6 13.7,-16.8 13.7,-28.3 0,-11.5 -5.4,-21.7 -13.7,-28.3 6.1,-4.8 13.8,-7.7 22.2,-7.7 19.9,0 36,16.2 36,36 z" class="st3" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
28
modules/ppcp-wc-gateway/assets/images/visa.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg3052" version="1.1" inkscape:version="0.48.5 r10040" width="3072" height="1919" sodipodi:docname="NoVictor_(Visa).png">
|
||||
<metadata id="metadata3058">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs3056"/>
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1366" inkscape:window-height="706" id="namedview3054" showgrid="false" inkscape:zoom="0.14039817" inkscape:cx="2929.9452" inkscape:cy="708.7338" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="svg3052"/>
|
||||
<g id="g3177">
|
||||
<path inkscape:connector-curvature="0" id="rect3062" d="m 17.981418,14.57961 3037.559182,0 0,1890.69839 -3037.559182,0 z" style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:#0061b2;stroke-width:31.99999808999999800;stroke-opacity:1"/>
|
||||
<path style="fill:#0061b2;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 120.56877,132.88731 2813.55253,0 0,397.72016 -2813.55253,0 z" id="path3065" inkscape:connector-curvature="0"/>
|
||||
<path inkscape:connector-curvature="0" id="path3069" d="m 120.56877,1389.7364 2813.55253,0 0,397.7202 -2813.55253,0 z" style="fill:#fdb827;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="path3071" d="m 588.28125,631.78125 0.0312,0.1875 -115.65625,0 0,19.59375 0,0.0625 c 90.26259,2.8715 117.21199,45.34099 127.1875,94.78125 l 53.21875,527.74995 175.125,0 374.1563,-642.37495 -175.125,0 -224.87505,386.09375 -38.9375,-386.09375 z" style="fill:#0061b2;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccc" inkscape:connector-curvature="0" id="rect3086" d="m 1295.6167,631.40088 169.9694,0 -208.4532,642.99782 -169.9694,0 z" style="fill:#0061b2;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" id="path3089" d="m 2232.0625,644.21875 -328.7187,630.18745 184.4062,0 47.9688,-96.2187 214.0624,0 7.3438,96.2187 169.9688,0 L 2479,644.21875 c -82.3125,0 -164.625,0 -246.9375,0 z m 89.3125,161.71875 20.3438,266.4375 -153.2188,0 z" style="fill:#0061b2;fill-opacity:1;fill-rule:evenodd;stroke:none"/>
|
||||
<path sodipodi:nodetypes="ssccssssccsss" inkscape:connector-curvature="0" id="path3105" d="m 1507.2767,794.95644 c 25.5058,-101.9596 109.2293,-171.57299 251.7473,-171.57299 133.5021,0 232.5054,83.38126 232.5054,83.38126 l -101.0196,105.83007 c 0,0 -74.6732,-57.72549 -118.658,-57.72549 -58.1586,0 -84.422,21.23645 -89.7952,56.122 -10.7138,69.55953 237.1425,112.13143 229.2985,274.19611 -5.2383,108.2296 -117.2546,213.2636 -245.3333,213.2636 -192.0571,0 -287.024,-76.9673 -287.024,-76.9673 l 86.5882,-123.4684 c 0,0 86.7945,69.524 168.3661,65.7429 55.0339,-2.551 97.451,-23.6415 94.6056,-60.9325 -6.4494,-84.5247 -267.4465,-123.32269 -221.281,-307.86926 z" style="fill:#0061b2;stroke:none;fill-opacity:1"/>
|
||||
<path inkscape:connector-curvature="0" id="path3151" d="m 2547.2051,644.19819 c -5.9321,7e-5 -11.7445,1.52282 -17.3956,4.56872 -5.651,3.04604 -10.044,7.42901 -13.213,13.09914 -3.1689,5.67025 -4.7528,11.57737 -4.7527,17.73176 -1e-4,6.09198 1.5673,11.94871 4.6895,17.57202 3.122,5.62334 7.482,9.99069 13.0861,13.09914 5.6042,3.10845 11.4662,4.66457 17.5857,4.66457 6.1192,0 11.9813,-1.55612 17.5855,-4.66457 5.6042,-3.10845 9.948,-7.4758 13.0546,-13.09914 3.1064,-5.62331 4.6577,-11.48004 4.6577,-17.57202 0,-6.15439 -1.5678,-12.06151 -4.7211,-17.73176 -3.1534,-5.67013 -7.562,-10.0531 -13.2129,-13.09914 -5.6511,-3.0459 -11.4319,-4.56865 -17.3638,-4.56872 z m 0,5.87863 c 4.9328,7e-5 9.7343,1.25589 14.4487,3.80195 4.7142,2.54618 8.3884,6.19368 11.0266,10.9266 2.6381,4.73302 3.9606,9.669 3.9607,14.79244 -10e-5,5.09228 -1.2743,9.96223 -3.8657,14.6327 -2.5914,4.67051 -6.2484,8.31801 -10.9316,10.9266 -4.6832,2.60862 -9.5497,3.8978 -14.6387,3.8978 -5.0891,0 -9.9875,-1.28918 -14.6706,-3.8978 -4.6832,-2.60859 -8.3247,-6.25609 -10.9315,-10.9266 -2.6071,-4.67047 -3.8974,-9.54042 -3.8974,-14.6327 0,-5.12344 1.3068,-10.05942 3.9606,-14.79244 2.6538,-4.73292 6.328,-8.38042 11.0267,-10.9266 4.6988,-2.54606 9.5479,-3.80188 14.5122,-3.80195 z" style="font-size:60px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#0061b2;fill-opacity:1;font-family:Arial"/>
|
||||
<path inkscape:connector-curvature="0" id="path3147" d="m 2532.5723,660.11513 0,41.68888 6.1748,0 0,-17.71165 3.6283,0 c 2.164,3e-5 3.8045,0.47681 4.9335,1.43513 1.6307,1.30067 3.7954,4.56264 6.4612,9.73091 l 3.3737,6.54561 7.5115,0 -4.6468,-8.15576 c -2.2268,-3.86764 -4.097,-6.61784 -5.6337,-8.26077 -0.8154,-0.85565 -1.898,-1.58908 -3.2465,-2.2052 3.2929,-0.27379 5.9337,-1.55633 7.9252,-3.81536 1.9915,-2.25895 2.9919,-4.89948 2.992,-7.94574 -1e-4,-2.15627 -0.6226,-4.1738 -1.8143,-6.09057 -1.1917,-1.91667 -2.7671,-3.2902 -4.7742,-4.06038 -2.0072,-0.77004 -5.2548,-1.15505 -9.7395,-1.1551 l -13.1452,0 z m 6.1748,5.67052 7.0023,0 c 3.0106,6e-5 5.0931,0.22094 6.2064,0.70007 1.1134,0.47922 1.9827,1.22979 2.61,2.2052 0.6272,0.97552 0.923,2.05819 0.923,3.29031 0,1.91677 -0.6401,3.45675 -1.9415,4.62043 -1.3016,1.16377 -3.7454,1.75021 -7.3206,1.75016 l -7.4796,0 0,-12.56617 z" style="font-size:60px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#0061b2;fill-opacity:1;font-family:Arial"/>
|
||||
<path style="font-size:60px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#0061b2;fill-opacity:1;font-family:Arial" d="m 2873.1269,1692.3949 c -5.9321,10e-5 -11.7445,1.5229 -17.3956,4.5688 -5.651,3.046 -10.044,7.429 -13.213,13.0991 -3.1689,5.6702 -4.7528,11.5774 -4.7527,17.7318 -1e-4,6.0919 1.5673,11.9487 4.6895,17.572 3.122,5.6233 7.482,9.9907 13.0861,13.0991 5.6042,3.1085 11.4662,4.6646 17.5857,4.6646 6.1192,0 11.9813,-1.5561 17.5855,-4.6646 5.6042,-3.1084 9.948,-7.4758 13.0546,-13.0991 3.1064,-5.6233 4.6577,-11.4801 4.6577,-17.572 0,-6.1544 -1.5678,-12.0616 -4.7211,-17.7318 -3.1534,-5.6701 -7.562,-10.0531 -13.2129,-13.0991 -5.6511,-3.0459 -11.4319,-4.5687 -17.3638,-4.5688 z m 0,5.8787 c 4.9328,0 9.7343,1.2559 14.4487,3.8019 4.7142,2.5462 8.3884,6.1937 11.0266,10.9266 2.6381,4.733 3.9606,9.669 3.9607,14.7925 -10e-5,5.0922 -1.2743,9.9622 -3.8657,14.6327 -2.5914,4.6705 -6.2484,8.318 -10.9316,10.9266 -4.6832,2.6086 -9.5497,3.8978 -14.6387,3.8978 -5.0891,0 -9.9875,-1.2892 -14.6706,-3.8978 -4.6832,-2.6086 -8.3247,-6.2561 -10.9315,-10.9266 -2.6071,-4.6705 -3.8974,-9.5405 -3.8974,-14.6327 0,-5.1235 1.3068,-10.0595 3.9606,-14.7925 2.6538,-4.7329 6.328,-8.3804 11.0267,-10.9266 4.6988,-2.546 9.5479,-3.8019 14.5122,-3.8019 z" id="path3159" inkscape:connector-curvature="0"/>
|
||||
<path style="font-size:60px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#0061b2;fill-opacity:1;font-family:Arial" d="m 2858.4941,1708.3119 0,41.6889 6.1748,0 0,-17.7117 3.6283,0 c 2.164,0 3.8045,0.4768 4.9335,1.4351 1.6307,1.3007 3.7954,4.5627 6.4612,9.731 l 3.3737,6.5456 7.5115,0 -4.6468,-8.1558 c -2.2268,-3.8676 -4.097,-6.6178 -5.6337,-8.2608 -0.8154,-0.8556 -1.898,-1.5891 -3.2465,-2.2052 3.2929,-0.2738 5.9337,-1.5563 7.9252,-3.8153 1.9915,-2.259 2.9919,-4.8995 2.992,-7.9458 -10e-5,-2.1562 -0.6226,-4.1738 -1.8143,-6.0905 -1.1917,-1.9167 -2.7671,-3.2902 -4.7742,-4.0604 -2.0072,-0.7701 -5.2548,-1.1551 -9.7395,-1.1551 l -13.1452,0 z m 6.1748,5.6705 7.0023,0 c 3.0106,10e-5 5.0931,0.2209 6.2064,0.7001 1.1134,0.4792 1.9827,1.2298 2.61,2.2052 0.6272,0.9755 0.923,2.0582 0.923,3.2903 0,1.9167 -0.6401,3.4567 -1.9415,4.6204 -1.3016,1.1638 -3.7454,1.7502 -7.3206,1.7502 l -7.4796,0 0,-12.5662 z" id="path3161" inkscape:connector-curvature="0"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.2 KiB |
20
modules/ppcp-wc-gateway/composer.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "inpsyde/ppcp-wc-gateway",
|
||||
"type": "inpsyde-module",
|
||||
"require": {
|
||||
"dhii/module-interface": "0.2.x-dev",
|
||||
"inpsyde/ppcp-session": "dev-master",
|
||||
"inpsyde/ppcp-admin-notices": "dev-master",
|
||||
"inpsyde/ppcp-api-client": "dev-master"
|
||||
},
|
||||
"scripts": {
|
||||
"unit": "./vendor/bin/phpunit --coverage-html build/coverage-report"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.1",
|
||||
"brain/monkey": "^2.4",
|
||||
"inpsyde/php-coding-standards": "^1"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
92
modules/ppcp-wc-gateway/extensions.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
/**
|
||||
* The extensions of the gateway module.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use Inpsyde\Woocommerce\Logging\Logger\NullLogger;
|
||||
use Inpsyde\Woocommerce\Logging\Logger\WooCommerceLogger;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
return array(
|
||||
|
||||
'api.merchant_email' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
|
||||
},
|
||||
'api.merchant_id' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
|
||||
},
|
||||
'api.partner_merchant_id' => static function (): string {
|
||||
// @ToDo: Replace with the real merchant id of platform
|
||||
return 'KQ8FCM66JFGDL';
|
||||
},
|
||||
'api.key' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
|
||||
return $key;
|
||||
},
|
||||
'api.secret' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
|
||||
},
|
||||
'api.prefix' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
|
||||
},
|
||||
'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
|
||||
$order_factory = $container->get( 'api.factory.order' );
|
||||
$patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
/**
|
||||
* The session handler.
|
||||
*
|
||||
* @var SessionHandler $session_handler
|
||||
*/
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
$bn_code = $session_handler->bn_code();
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings $settings
|
||||
*/
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
||||
$application_context_repository = $container->get( 'api.repository.application-context' );
|
||||
$pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
|
||||
return new OrderEndpoint(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$order_factory,
|
||||
$patch_collection_factory,
|
||||
$intent,
|
||||
$logger,
|
||||
$application_context_repository,
|
||||
$pay_pal_request_id_repository,
|
||||
$bn_code
|
||||
);
|
||||
},
|
||||
'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
|
||||
return new NullLogger();
|
||||
}
|
||||
|
||||
$source = $container->get( 'woocommerce.logger.source' );
|
||||
return new WooCommerceLogger(
|
||||
wc_get_logger(),
|
||||
$source
|
||||
);
|
||||
},
|
||||
);
|
16
modules/ppcp-wc-gateway/module.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* The module.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway;
|
||||
|
||||
use Dhii\Modular\Module\ModuleInterface;
|
||||
|
||||
return static function (): ModuleInterface {
|
||||
return new WcGatewayModule();
|
||||
};
|
20
modules/ppcp-wc-gateway/phpunit.xml.dist
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
bootstrap="vendor/autoload.php"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory suffix="Test.php">./tests/PHPUnit</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
1573
modules/ppcp-wc-gateway/services.php
Normal file
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
/**
|
||||
* Renders the columns to display to the merchant, which orders have been authorized and
|
||||
* which have not been authorized yet.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Admin
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Admin;
|
||||
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class OrderTablePaymentStatusColumn
|
||||
*/
|
||||
class OrderTablePaymentStatusColumn {
|
||||
|
||||
private const COLUMN_KEY = 'ppcp_payment_status';
|
||||
private const INTENT = 'authorize';
|
||||
private const AFTER_COLUMN_KEY = 'order_status';
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* OrderTablePaymentStatusColumn constructor.
|
||||
*
|
||||
* @param Settings $settings The Settings.
|
||||
*/
|
||||
public function __construct( Settings $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the columns.
|
||||
*
|
||||
* @param array $columns The existing columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function register( array $columns ): array {
|
||||
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
$status_column_position = array_search( self::AFTER_COLUMN_KEY, array_keys( $columns ), true );
|
||||
$to_insert_position = false === $status_column_position ? count( $columns ) : $status_column_position + 1;
|
||||
|
||||
$columns = array_merge(
|
||||
array_slice( $columns, 0, $to_insert_position ),
|
||||
array(
|
||||
self::COLUMN_KEY => __( 'Payment Captured', 'paypal-for-woocommerce' ),
|
||||
),
|
||||
array_slice( $columns, $to_insert_position )
|
||||
);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the column.
|
||||
*
|
||||
* @param string $column The column.
|
||||
* @param int $wc_order_id The id or the Woocommerce order.
|
||||
*/
|
||||
public function render( string $column, int $wc_order_id ) {
|
||||
if ( ! $this->settings->has( 'intent' ) || $this->settings->get( 'intent' ) !== self::INTENT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self::COLUMN_KEY !== $column ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $wc_order_id );
|
||||
|
||||
if ( ! is_a( $wc_order, \WC_Order::class ) || ! $this->render_for_order( $wc_order ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->is_captured( $wc_order ) ) {
|
||||
$this->render_completed_status();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->render_incomplete_status();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to render the authorization status of an order or not.
|
||||
*
|
||||
* @param \WC_Order $order The Woocommerce order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function render_for_order( \WC_Order $order ): bool {
|
||||
return ! empty( $order->get_meta( PayPalGateway::CAPTURED_META_KEY ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the order has been captured or not.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_captured( \WC_Order $wc_order ): bool {
|
||||
$captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
||||
return wc_string_to_bool( $captured );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the captured status.
|
||||
*/
|
||||
private function render_completed_status() {
|
||||
printf(
|
||||
'<span class="dashicons dashicons-yes">
|
||||
<span class="screen-reader-text">%s</span>
|
||||
</span>',
|
||||
esc_html__( 'Payment captured', 'paypal-for-woocommerce' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the "not captured" status.
|
||||
*/
|
||||
private function render_incomplete_status() {
|
||||
printf(
|
||||
'<mark class="onbackorder">%s</mark>',
|
||||
esc_html__( 'Not captured', 'paypal-for-woocommerce' )
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/**
|
||||
* Renders the not captured information.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Admin
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Admin;
|
||||
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class PaymentStatusOrderDetail
|
||||
*/
|
||||
class PaymentStatusOrderDetail {
|
||||
|
||||
/**
|
||||
* Renders the not captured information.
|
||||
*
|
||||
* @param int $wc_order_id The Woocommerce order id.
|
||||
*/
|
||||
public function render( int $wc_order_id ) {
|
||||
$wc_order = new \WC_Order( $wc_order_id );
|
||||
$intent = $wc_order->get_meta( PayPalGateway::INTENT_META_KEY );
|
||||
$captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
||||
|
||||
if ( strcasecmp( $intent, 'AUTHORIZE' ) !== 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $captured ) && wc_string_to_bool( $captured ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
// @phpcs:ignore Inpsyde.CodeQuality.LineLength.TooLong
|
||||
'<li class="wide"><p><mark class="order-status status-on-hold"><span>%1$s</span></mark></p><p>%2$s</p></li>',
|
||||
esc_html__(
|
||||
'Not captured',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
esc_html__(
|
||||
'To capture the payment select capture action from the list below.',
|
||||
'paypal-for-woocommerce'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
/**
|
||||
* Service that fills checkout address fields
|
||||
* with address selected via PayPal
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Checkout
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
|
||||
/**
|
||||
* Class CheckoutPayPalAddressPreset
|
||||
*/
|
||||
class CheckoutPayPalAddressPreset {
|
||||
|
||||
/**
|
||||
* Caches Shipping objects for orders.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $shipping_cache = array();
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
private $session_handler;
|
||||
|
||||
/**
|
||||
* CheckoutPayPalAddressPreset constructor.
|
||||
*
|
||||
* @param SessionHandler $session_handler The session handler.
|
||||
*/
|
||||
public function __construct( SessionHandler $session_handler ) {
|
||||
$this->session_handler = $session_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the checkout fields to replace values if necessary.
|
||||
*
|
||||
* @wp-hook woocommerce_checkout_get_value
|
||||
*
|
||||
* @param string|null $default_value The default value.
|
||||
* @param string $field_id The field ID.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function filter_checkout_field( $default_value, $field_id ): ?string {
|
||||
if ( ! is_string( $default_value ) ) {
|
||||
$default_value = null;
|
||||
}
|
||||
|
||||
if ( ! is_string( $field_id ) ) {
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
return $this->read_preset_for_field( $field_id ) ?? $default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for a checkout field from an PayPal order if given.
|
||||
*
|
||||
* @param string $field_id The ID of the field.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function read_preset_for_field( string $field_id ): ?string {
|
||||
$order = $this->session_handler->order();
|
||||
if ( ! $order ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$shipping = $this->read_shipping_from_order();
|
||||
$payer = $order->payer();
|
||||
|
||||
$address_map = array(
|
||||
'billing_address_1' => 'address_line_1',
|
||||
'billing_address_2' => 'address_line_2',
|
||||
'billing_postcode' => 'postal_code',
|
||||
'billing_country' => 'country_code',
|
||||
'billing_city' => 'admin_area_2',
|
||||
'billing_state' => 'admin_area_1',
|
||||
);
|
||||
$payer_name_map = array(
|
||||
'billing_last_name' => 'surname',
|
||||
'billing_first_name' => 'given_name',
|
||||
);
|
||||
$payer_map = array(
|
||||
'billing_email' => 'email_address',
|
||||
);
|
||||
$payer_phone_map = array(
|
||||
'billing_phone' => 'national_number',
|
||||
);
|
||||
|
||||
if ( array_key_exists( $field_id, $address_map ) && $shipping ) {
|
||||
return $shipping->address()->{$address_map[ $field_id ]}() ? $shipping->address()->{$address_map[ $field_id ]}() : null;
|
||||
}
|
||||
|
||||
if ( array_key_exists( $field_id, $payer_name_map ) && $payer ) {
|
||||
return $payer->name()->{$payer_name_map[ $field_id ]}() ? $payer->name()->{$payer_name_map[ $field_id ]}() : null;
|
||||
}
|
||||
|
||||
if ( array_key_exists( $field_id, $payer_map ) && $payer ) {
|
||||
return $payer->{$payer_map[ $field_id ]}() ? $payer->{$payer_map[ $field_id ]}() : null;
|
||||
}
|
||||
|
||||
if (
|
||||
array_key_exists( $field_id, $payer_phone_map )
|
||||
&& $payer
|
||||
&& $payer->phone()
|
||||
&& $payer->phone()->phone()
|
||||
) {
|
||||
return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Shipping object for an order, if given.
|
||||
*
|
||||
* @return Shipping|null
|
||||
*/
|
||||
private function read_shipping_from_order(): ?Shipping {
|
||||
$order = $this->session_handler->order();
|
||||
if ( ! $order ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( array_key_exists( $order->id(), $this->shipping_cache ) ) {
|
||||
return $this->shipping_cache[ $order->id() ];
|
||||
}
|
||||
|
||||
$shipping = null;
|
||||
foreach ( $this->session_handler->order()->purchase_units() as $unit ) {
|
||||
$shipping = $unit->shipping();
|
||||
if ( $shipping ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->shipping_cache[ $order->id() ] = $shipping;
|
||||
|
||||
return $shipping;
|
||||
}
|
||||
}
|
112
modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/**
|
||||
* Determines whether specific gateways need to be disabled.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Checkout
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
|
||||
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class DisableGateways
|
||||
*/
|
||||
class DisableGateways {
|
||||
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
private $session_handler;
|
||||
|
||||
/**
|
||||
* The Settings.
|
||||
*
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* DisableGateways constructor.
|
||||
*
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param ContainerInterface $settings The Settings.
|
||||
*/
|
||||
public function __construct(
|
||||
SessionHandler $session_handler,
|
||||
ContainerInterface $settings
|
||||
) {
|
||||
|
||||
$this->session_handler = $session_handler;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the logic for enabling/disabling gateways.
|
||||
*
|
||||
* @param array $methods The Gateways.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function handler( array $methods ): array {
|
||||
if ( ! isset( $methods[ PayPalGateway::ID ] ) && ! isset( $methods[ CreditCardGateway::ID ] ) ) {
|
||||
return $methods;
|
||||
}
|
||||
if (
|
||||
! $this->settings->has( 'merchant_email' )
|
||||
|| ! is_email( $this->settings->get( 'merchant_email' ) )
|
||||
) {
|
||||
unset( $methods[ PayPalGateway::ID ] );
|
||||
unset( $methods[ CreditCardGateway::ID ] );
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if ( ! $this->settings->has( 'client_id' ) || empty( $this->settings->get( 'client_id' ) ) ) {
|
||||
unset( $methods[ CreditCardGateway::ID ] );
|
||||
}
|
||||
|
||||
if ( ! $this->needs_to_disable_gateways() ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if ( $this->is_credit_card() ) {
|
||||
return array( CreditCardGateway::ID => $methods[ CreditCardGateway::ID ] );
|
||||
}
|
||||
return array( PayPalGateway::ID => $methods[ PayPalGateway::ID ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Gateways need to be disabled. When we come to the checkout with a running PayPal
|
||||
* session, we need to disable the other Gateways, so the customer can smoothly sail through the
|
||||
* process.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needs_to_disable_gateways(): bool {
|
||||
return $this->session_handler->order() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current PayPal session is done via DCC payment.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_credit_card(): bool {
|
||||
$order = $this->session_handler->order();
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! $order->payment_source() || ! $order->payment_source()->card() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/**
|
||||
* Controls the endpoint for customers returning from PayPal.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Inpsyde\PayPalCommerce\Webhooks\Handler\PrefixTrait;
|
||||
|
||||
/**
|
||||
* Class ReturnUrlEndpoint
|
||||
*/
|
||||
class ReturnUrlEndpoint {
|
||||
|
||||
use PrefixTrait;
|
||||
public const ENDPOINT = 'ppc-return-url';
|
||||
|
||||
/**
|
||||
* The PayPal Gateway.
|
||||
*
|
||||
* @var PayPalGateway
|
||||
*/
|
||||
private $gateway;
|
||||
|
||||
/**
|
||||
* The Order Endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* ReturnUrlEndpoint constructor.
|
||||
*
|
||||
* @param PayPalGateway $gateway The PayPal Gateway.
|
||||
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||
* @param string $prefix The prefix.
|
||||
*/
|
||||
public function __construct( PayPalGateway $gateway, OrderEndpoint $order_endpoint, string $prefix ) {
|
||||
$this->gateway = $gateway;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the incoming request.
|
||||
*/
|
||||
public function handle_request() {
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! isset( $_GET['token'] ) ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
$order = $this->order_endpoint->order( $token );
|
||||
if ( ! $order ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
|
||||
if ( ! $wc_order_id ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $wc_order_id );
|
||||
if ( ! $wc_order ) {
|
||||
exit();
|
||||
}
|
||||
|
||||
$success = $this->gateway->process_payment( $wc_order_id );
|
||||
if ( isset( $success['result'] ) && 'success' === $success['result'] ) {
|
||||
wp_safe_redirect( $success['redirect'] );
|
||||
exit();
|
||||
}
|
||||
wp_safe_redirect( wc_get_checkout_url() );
|
||||
exit();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* The Not Found Exception for the Settings Container.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Exception
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Exception;
|
||||
|
||||
use Exception;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class NotFoundException
|
||||
*/
|
||||
class NotFoundException extends Exception implements NotFoundExceptionInterface {
|
||||
|
||||
|
||||
}
|
214
modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php
Normal file
|
@ -0,0 +1,214 @@
|
|||
<?php
|
||||
/**
|
||||
* The Credit card gateway.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class CreditCardGateway
|
||||
*/
|
||||
class CreditCardGateway extends PayPalGateway {
|
||||
|
||||
public const ID = 'ppcp-credit-card-gateway';
|
||||
|
||||
/**
|
||||
* The URL to the module.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* CreditCardGateway constructor.
|
||||
*
|
||||
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
||||
* @param OrderProcessor $order_processor The Order processor.
|
||||
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
|
||||
* @param AuthorizeOrderActionNotice $notice The Notices.
|
||||
* @param ContainerInterface $config The settings.
|
||||
* @param string $module_url The URL to the module.
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
*/
|
||||
public function __construct(
|
||||
SettingsRenderer $settings_renderer,
|
||||
OrderProcessor $order_processor,
|
||||
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||
AuthorizeOrderActionNotice $notice,
|
||||
ContainerInterface $config,
|
||||
string $module_url,
|
||||
SessionHandler $session_handler
|
||||
) {
|
||||
|
||||
$this->id = self::ID;
|
||||
$this->order_processor = $order_processor;
|
||||
$this->authorized_payments = $authorized_payments_processor;
|
||||
$this->notice = $notice;
|
||||
$this->settings_renderer = $settings_renderer;
|
||||
$this->config = $config;
|
||||
$this->session_handler = $session_handler;
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
&& $this->config->has( 'vault_enabled' )
|
||||
&& $this->config->get( 'vault_enabled' )
|
||||
) {
|
||||
$this->supports = array(
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
);
|
||||
}
|
||||
|
||||
$this->method_title = __(
|
||||
'PayPal Credit Card Processing',
|
||||
'paypal-for-woocommerce'
|
||||
);
|
||||
$this->method_description = __(
|
||||
'Provide your customers with the option to pay with credit card.',
|
||||
'paypal-for-woocommerce'
|
||||
);
|
||||
$this->title = $this->config->has( 'dcc_gateway_title' ) ?
|
||||
$this->config->get( 'dcc_gateway_title' ) : $this->method_title;
|
||||
$this->description = $this->config->has( 'dcc_gateway_description' ) ?
|
||||
$this->config->get( 'dcc_gateway_description' ) : $this->method_description;
|
||||
|
||||
$this->init_form_fields();
|
||||
$this->init_settings();
|
||||
|
||||
add_action(
|
||||
'woocommerce_update_options_payment_gateways_' . $this->id,
|
||||
array(
|
||||
$this,
|
||||
'process_admin_options',
|
||||
)
|
||||
);
|
||||
|
||||
$this->module_url = $module_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the form fields.
|
||||
*/
|
||||
public function init_form_fields() {
|
||||
$this->form_fields = array(
|
||||
'enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'paypal-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Enable Credit Card Payments', 'paypal-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
),
|
||||
'ppcp' => array(
|
||||
'type' => 'ppcp',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the settings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_ppcp_html(): string {
|
||||
|
||||
ob_start();
|
||||
$this->settings_renderer->render( true );
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of the gateway.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
|
||||
if ( is_admin() ) {
|
||||
return parent::get_title();
|
||||
}
|
||||
$title = parent::get_title();
|
||||
$icons = $this->config->has( 'card_icons' ) ? (array) $this->config->get( 'card_icons' ) : array();
|
||||
if ( empty( $icons ) ) {
|
||||
return $title;
|
||||
}
|
||||
|
||||
$title_options = $this->card_labels();
|
||||
$images = array_map(
|
||||
function ( string $type ) use ( $title_options ): string {
|
||||
return '<img
|
||||
title="' . esc_attr( $title_options[ $type ] ) . '"
|
||||
src="' . esc_url( $this->module_url ) . '/assets/images/' . esc_attr( $type ) . '.svg"
|
||||
class="ppcp-card-icon"
|
||||
> ';
|
||||
},
|
||||
$icons
|
||||
);
|
||||
return $title . implode( '', $images );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of credit card names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function card_labels(): array {
|
||||
return array(
|
||||
'visa' => _x(
|
||||
'Visa',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'mastercard' => _x(
|
||||
'Mastercard',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'amex' => _x(
|
||||
'American Express',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'discover' => _x(
|
||||
'Discover',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'jcb' => _x(
|
||||
'JCB',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'elo' => _x(
|
||||
'Elo',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'hiper' => _x(
|
||||
'Hiper',
|
||||
'Name of credit card',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
292
modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php
Normal file
|
@ -0,0 +1,292 @@
|
|||
<?php
|
||||
/**
|
||||
* The PayPal Payment Gateway
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class PayPalGateway
|
||||
*/
|
||||
class PayPalGateway extends \WC_Payment_Gateway {
|
||||
|
||||
public const ID = 'ppcp-gateway';
|
||||
public const CAPTURED_META_KEY = '_ppcp_paypal_captured';
|
||||
public const INTENT_META_KEY = '_ppcp_paypal_intent';
|
||||
public const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
||||
|
||||
/**
|
||||
* The Settings Renderer.
|
||||
*
|
||||
* @var SettingsRenderer
|
||||
*/
|
||||
protected $settings_renderer;
|
||||
|
||||
/**
|
||||
* The processor for authorized payments.
|
||||
*
|
||||
* @var AuthorizedPaymentsProcessor
|
||||
*/
|
||||
protected $authorized_payments;
|
||||
|
||||
/**
|
||||
* The Authorized Order Action Notice.
|
||||
*
|
||||
* @var AuthorizeOrderActionNotice
|
||||
*/
|
||||
protected $notice;
|
||||
|
||||
/**
|
||||
* The processor for orders.
|
||||
*
|
||||
* @var OrderProcessor
|
||||
*/
|
||||
protected $order_processor;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
protected $session_handler;
|
||||
|
||||
/**
|
||||
* PayPalGateway constructor.
|
||||
*
|
||||
* @param SettingsRenderer $settings_renderer The Settings Renderer.
|
||||
* @param OrderProcessor $order_processor The Order Processor.
|
||||
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
|
||||
* @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
|
||||
* @param ContainerInterface $config The settings.
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
*/
|
||||
public function __construct(
|
||||
SettingsRenderer $settings_renderer,
|
||||
OrderProcessor $order_processor,
|
||||
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||
AuthorizeOrderActionNotice $notice,
|
||||
ContainerInterface $config,
|
||||
SessionHandler $session_handler
|
||||
) {
|
||||
|
||||
$this->id = self::ID;
|
||||
$this->order_processor = $order_processor;
|
||||
$this->authorized_payments = $authorized_payments_processor;
|
||||
$this->notice = $notice;
|
||||
$this->settings_renderer = $settings_renderer;
|
||||
$this->config = $config;
|
||||
$this->session_handler = $session_handler;
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
&& $this->config->has( 'vault_enabled' )
|
||||
&& $this->config->get( 'vault_enabled' )
|
||||
) {
|
||||
$this->supports = array(
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
);
|
||||
}
|
||||
|
||||
$this->method_title = __( 'PayPal', 'paypal-for-woocommerce' );
|
||||
$this->method_description = __(
|
||||
'Provide your customers with the PayPal payment option.',
|
||||
'paypal-for-woocommerce'
|
||||
);
|
||||
$this->title = $this->config->has( 'title' ) ?
|
||||
$this->config->get( 'title' ) : $this->method_title;
|
||||
$this->description = $this->config->has( 'description' ) ?
|
||||
$this->config->get( 'description' ) : $this->method_description;
|
||||
|
||||
$this->init_form_fields();
|
||||
$this->init_settings();
|
||||
|
||||
add_action(
|
||||
'woocommerce_update_options_payment_gateways_' . $this->id,
|
||||
array(
|
||||
$this,
|
||||
'process_admin_options',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Gateway needs to be setup.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function needs_setup(): bool {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the form fields.
|
||||
*/
|
||||
public function init_form_fields() {
|
||||
$this->form_fields = array(
|
||||
'enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'paypal-for-woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Enable PayPal Payments', 'paypal-for-woocommerce' ),
|
||||
'default' => 'no',
|
||||
),
|
||||
'ppcp' => array(
|
||||
'type' => 'ppcp',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a payment for an Woocommerce order.
|
||||
*
|
||||
* @param int $order_id The Woocommerce order id.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function process_payment( $order_id ): ?array {
|
||||
global $woocommerce;
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, \WC_Order::class ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the WC_Order is payed through the approved webhook.
|
||||
*/
|
||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $this->get_return_url( $wc_order ),
|
||||
);
|
||||
}
|
||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
try {
|
||||
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) {
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $this->get_return_url( $wc_order ),
|
||||
);
|
||||
}
|
||||
} catch ( PayPalApiException $error ) {
|
||||
if ( $error->has_detail( 'INSTRUMENT_DECLINED' ) ) {
|
||||
$host = $this->config->has( 'sandbox_on' ) && $this->config->get( 'sandbox_on' ) ?
|
||||
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/';
|
||||
$url = $host . 'checkoutnow?token=' . $this->session_handler->order()->id();
|
||||
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $url,
|
||||
);
|
||||
}
|
||||
|
||||
$this->session_handler->destroy_session_data();
|
||||
}
|
||||
wc_add_notice(
|
||||
$this->order_processor->last_error(),
|
||||
'error'
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures an authorized payment for an Woocommerce order.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function capture_authorized_payment( \WC_Order $wc_order ): bool {
|
||||
$is_processed = $this->authorized_payments->process( $wc_order );
|
||||
$this->render_authorization_message_for_status( $this->authorized_payments->last_status() );
|
||||
|
||||
if ( $is_processed ) {
|
||||
$wc_order->add_order_note(
|
||||
__( 'Payment successfully captured.', 'paypal-for-woocommerce' )
|
||||
);
|
||||
|
||||
$wc_order->set_status( 'processing' );
|
||||
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->save();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->authorized_payments->last_status() === AuthorizedPaymentsProcessor::ALREADY_CAPTURED ) {
|
||||
if ( $wc_order->get_status() === 'on-hold' ) {
|
||||
$wc_order->add_order_note(
|
||||
__( 'Payment successfully captured.', 'paypal-for-woocommerce' )
|
||||
);
|
||||
$wc_order->set_status( 'processing' );
|
||||
}
|
||||
|
||||
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the notice for a status.
|
||||
*
|
||||
* @param string $status The status.
|
||||
*/
|
||||
private function render_authorization_message_for_status( string $status ) {
|
||||
|
||||
$message_mapping = array(
|
||||
AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
|
||||
AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
|
||||
AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
|
||||
AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
|
||||
);
|
||||
$display_message = ( isset( $message_mapping[ $status ] ) ) ?
|
||||
$message_mapping[ $status ]
|
||||
: AuthorizeOrderActionNotice::FAILED;
|
||||
$this->notice->display_message( $display_message );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the settings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_ppcp_html(): string {
|
||||
|
||||
ob_start();
|
||||
$this->settings_renderer->render( false );
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* The WcGateway interface.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Gateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
/**
|
||||
* Interface WcGatewayInterface
|
||||
*/
|
||||
interface WcGatewayInterface {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/**
|
||||
* Contains the messages to display, when capturing an authorization manually.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Notice
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Notice;
|
||||
|
||||
use Inpsyde\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
|
||||
/**
|
||||
* Class AuthorizeOrderActionNotice
|
||||
*/
|
||||
class AuthorizeOrderActionNotice {
|
||||
|
||||
public const QUERY_PARAM = 'ppcp-authorized-message';
|
||||
|
||||
public const NO_INFO = 81;
|
||||
public const ALREADY_CAPTURED = 82;
|
||||
public const FAILED = 83;
|
||||
public const SUCCESS = 84;
|
||||
public const NOT_FOUND = 85;
|
||||
|
||||
/**
|
||||
* Returns the current message if there is one.
|
||||
*
|
||||
* @return Message|null
|
||||
*/
|
||||
public function message(): ?Message {
|
||||
|
||||
$message = $this->current_message();
|
||||
if ( ! $message ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Message( $message['message'], $message['type'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current message.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function current_message(): array {
|
||||
$messages[ self::NO_INFO ] = array(
|
||||
'message' => __(
|
||||
'Could not retrieve information. Try again later.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'type' => 'error',
|
||||
);
|
||||
$messages[ self::ALREADY_CAPTURED ] = array(
|
||||
'message' => __(
|
||||
'Payment already captured.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'type' => 'error',
|
||||
);
|
||||
$messages[ self::FAILED ] = array(
|
||||
'message' => __(
|
||||
'Failed to capture. Try again later.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'type' => 'error',
|
||||
);
|
||||
$messages[ self::NOT_FOUND ] = array(
|
||||
'message' => __(
|
||||
'Could not find payment to process.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'type' => 'error',
|
||||
);
|
||||
$messages[ self::SUCCESS ] = array(
|
||||
'message' => __(
|
||||
'Payment successfully captured.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'type' => 'success',
|
||||
);
|
||||
|
||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! isset( $_GET[ self::QUERY_PARAM ] ) ) { // Input ok.
|
||||
return array();
|
||||
}
|
||||
$message_id = absint( $_GET[ self::QUERY_PARAM ] ); // Input ok.
|
||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
return ( isset( $messages[ $message_id ] ) ) ? $messages[ $message_id ] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the query parameter for the message to 'redirect_post_location'.
|
||||
*
|
||||
* @param int $message_code The message code.
|
||||
*/
|
||||
public function display_message( int $message_code ): void {
|
||||
add_filter(
|
||||
'redirect_post_location',
|
||||
static function ( $location ) use ( $message_code ) {
|
||||
return add_query_arg(
|
||||
self::QUERY_PARAM,
|
||||
$message_code,
|
||||
$location
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* Registers the admin message to "connect your account" if necessary.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Notice
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Notice;
|
||||
|
||||
use Inpsyde\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class ConnectAdminNotice
|
||||
*/
|
||||
class ConnectAdminNotice {
|
||||
|
||||
/**
|
||||
* The state.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* ConnectAdminNotice constructor.
|
||||
*
|
||||
* @param State $state The state.
|
||||
* @param ContainerInterface $settings The settings.
|
||||
*/
|
||||
public function __construct( State $state, ContainerInterface $settings ) {
|
||||
$this->state = $state;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message.
|
||||
*
|
||||
* @return Message|null
|
||||
*/
|
||||
public function connect_message(): ?Message {
|
||||
if ( ! $this->should_display() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
/* translators: %1$s the gateway name. */
|
||||
__(
|
||||
'PayPal Payments is almost ready. To get started, <a href="%1$s">connect your account</a>.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
|
||||
);
|
||||
return new Message( $message, 'warning' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the message should display.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function should_display(): bool {
|
||||
return $this->state->current_state() < State::STATE_PROGRESSIVE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
/**
|
||||
* Authorizes payments for a given Woocommerce order.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Processor
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
||||
|
||||
use Exception;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class AuthorizedPaymentsProcessor
|
||||
*/
|
||||
class AuthorizedPaymentsProcessor {
|
||||
|
||||
public const SUCCESSFUL = 'SUCCESSFUL';
|
||||
public const ALREADY_CAPTURED = 'ALREADY_CAPTURED';
|
||||
public const FAILED = 'FAILED';
|
||||
public const INACCESSIBLE = 'INACCESSIBLE';
|
||||
public const NOT_FOUND = 'NOT_FOUND';
|
||||
|
||||
/**
|
||||
* The Order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* The Payments endpoint.
|
||||
*
|
||||
* @var PaymentsEndpoint
|
||||
*/
|
||||
private $payments_endpoint;
|
||||
|
||||
/**
|
||||
* The last status.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $last_status = '';
|
||||
|
||||
/**
|
||||
* AuthorizedPaymentsProcessor constructor.
|
||||
*
|
||||
* @param OrderEndpoint $order_endpoint The Order endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
OrderEndpoint $order_endpoint,
|
||||
PaymentsEndpoint $payments_endpoint
|
||||
) {
|
||||
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a Woocommerce order.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function process( \WC_Order $wc_order ): bool {
|
||||
try {
|
||||
$order = $this->paypal_order_from_wc_order( $wc_order );
|
||||
} catch ( Exception $exception ) {
|
||||
if ( $exception->getCode() === 404 ) {
|
||||
$this->last_status = self::NOT_FOUND;
|
||||
return false;
|
||||
}
|
||||
$this->last_status = self::INACCESSIBLE;
|
||||
return false;
|
||||
}
|
||||
|
||||
$authorizations = $this->all_authorizations( $order );
|
||||
|
||||
if ( ! $this->are_authorzations_to_capture( ...$authorizations ) ) {
|
||||
$this->last_status = self::ALREADY_CAPTURED;
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->capture_authorizations( ...$authorizations );
|
||||
} catch ( Exception $exception ) {
|
||||
$this->last_status = self::FAILED;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->last_status = self::SUCCESSFUL;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last status.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function last_status(): string {
|
||||
|
||||
return $this->last_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PayPal order from a given Woocommerce order.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
*
|
||||
* @return Order
|
||||
*/
|
||||
private function paypal_order_from_wc_order( \WC_Order $wc_order ): Order {
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
return $this->order_endpoint->order( $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Authorizations from an order.
|
||||
*
|
||||
* @param Order $order The order.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function all_authorizations( Order $order ): array {
|
||||
$authorizations = array();
|
||||
foreach ( $order->purchase_units() as $purchase_unit ) {
|
||||
foreach ( $purchase_unit->payments()->authorizations() as $authorization ) {
|
||||
$authorizations[] = $authorization;
|
||||
}
|
||||
}
|
||||
|
||||
return $authorizations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether Authorizations need to be captured.
|
||||
*
|
||||
* @param Authorization ...$authorizations All Authorizations.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function are_authorzations_to_capture( Authorization ...$authorizations ): bool {
|
||||
return (bool) count( $this->authorizations_to_capture( ...$authorizations ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the authorizations.
|
||||
*
|
||||
* @param Authorization ...$authorizations All authorizations.
|
||||
*/
|
||||
private function capture_authorizations( Authorization ...$authorizations ) {
|
||||
$uncaptured_authorizations = $this->authorizations_to_capture( ...$authorizations );
|
||||
foreach ( $uncaptured_authorizations as $authorization ) {
|
||||
$this->payments_endpoint->capture( $authorization->id() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The authorizations which need to be captured.
|
||||
*
|
||||
* @param Authorization ...$authorizations All Authorizations.
|
||||
* @return Authorization[]
|
||||
*/
|
||||
private function authorizations_to_capture( Authorization ...$authorizations ): array {
|
||||
return array_filter(
|
||||
$authorizations,
|
||||
static function ( Authorization $authorization ): bool {
|
||||
return $authorization->status()->is( AuthorizationStatus::CREATED )
|
||||
|| $authorization->status()->is( AuthorizationStatus::PENDING );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
272
modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php
Normal file
|
@ -0,0 +1,272 @@
|
|||
<?php
|
||||
/**
|
||||
* Processes orders for the gateways.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Processor
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Processor;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
|
||||
use Inpsyde\PayPalCommerce\Button\Helper\ThreeDSecure;
|
||||
use Inpsyde\PayPalCommerce\Session\SessionHandler;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class OrderProcessor
|
||||
*/
|
||||
class OrderProcessor {
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
private $session_handler;
|
||||
|
||||
/**
|
||||
* The Cart Repository.
|
||||
*
|
||||
* @var CartRepository
|
||||
*/
|
||||
private $cart_repository;
|
||||
|
||||
/**
|
||||
* The Order Endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* The Payments Endpoint.
|
||||
*
|
||||
* @var PaymentsEndpoint
|
||||
*/
|
||||
private $payments_endpoint;
|
||||
|
||||
/**
|
||||
* The Order Factory.
|
||||
*
|
||||
* @var OrderFactory
|
||||
*/
|
||||
private $order_factory;
|
||||
|
||||
/**
|
||||
* The helper for 3d secure.
|
||||
*
|
||||
* @var ThreeDSecure
|
||||
*/
|
||||
private $threed_secure;
|
||||
|
||||
/**
|
||||
* The processor for authorized payments.
|
||||
*
|
||||
* @var AuthorizedPaymentsProcessor
|
||||
*/
|
||||
private $authorized_payments_processor;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The last error.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $last_error = '';
|
||||
|
||||
/**
|
||||
* OrderProcessor constructor.
|
||||
*
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param CartRepository $cart_repository The Cart Repository.
|
||||
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The Payments Endpoint.
|
||||
* @param OrderFactory $order_factory The Order Factory.
|
||||
* @param ThreeDSecure $three_d_secure The ThreeDSecure Helper.
|
||||
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
|
||||
* @param Settings $settings The Settings.
|
||||
*/
|
||||
public function __construct(
|
||||
SessionHandler $session_handler,
|
||||
CartRepository $cart_repository,
|
||||
OrderEndpoint $order_endpoint,
|
||||
PaymentsEndpoint $payments_endpoint,
|
||||
OrderFactory $order_factory,
|
||||
ThreeDSecure $three_d_secure,
|
||||
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||
Settings $settings
|
||||
) {
|
||||
|
||||
$this->session_handler = $session_handler;
|
||||
$this->cart_repository = $cart_repository;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
$this->order_factory = $order_factory;
|
||||
$this->threed_secure = $three_d_secure;
|
||||
$this->authorized_payments_processor = $authorized_payments_processor;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a given Woocommerce order and captured/authorizes the connected PayPal orders.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
* @param \WooCommerce $woocommerce The Woocommerce object.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool {
|
||||
$order = $this->session_handler->order();
|
||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||
|
||||
$error_message = null;
|
||||
if ( ! $order || ! $this->order_is_approved( $order ) ) {
|
||||
$error_message = __(
|
||||
'The payment has not been approved yet.',
|
||||
'paypal-for-woocommerce'
|
||||
);
|
||||
}
|
||||
if ( $error_message ) {
|
||||
$this->last_error = sprintf(
|
||||
// translators: %s is the message of the error.
|
||||
__( 'Payment error: %s', 'paypal-for-woocommerce' ),
|
||||
$error_message
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = $this->patch_order( $wc_order, $order );
|
||||
if ( $order->intent() === 'CAPTURE' ) {
|
||||
$order = $this->order_endpoint->capture( $order );
|
||||
}
|
||||
|
||||
if ( $order->intent() === 'AUTHORIZE' ) {
|
||||
$order = $this->order_endpoint->authorize( $order );
|
||||
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
|
||||
}
|
||||
|
||||
$wc_order->update_status(
|
||||
'on-hold',
|
||||
__( 'Awaiting payment.', 'paypal-for-woocommerce' )
|
||||
);
|
||||
if ( $order->status()->is( OrderStatus::COMPLETED ) && $order->intent() === 'CAPTURE' ) {
|
||||
$wc_order->update_status(
|
||||
'processing',
|
||||
__( 'Payment received.', 'paypal-for-woocommerce' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->capture_authorized_downloads( $order ) && $this->authorized_payments_processor->process( $wc_order ) ) {
|
||||
$wc_order->add_order_note(
|
||||
__( 'Payment successfully captured.', 'paypal-for-woocommerce' )
|
||||
);
|
||||
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->update_status( 'processing' );
|
||||
}
|
||||
$woocommerce->cart->empty_cart();
|
||||
$this->session_handler->destroy_session_data();
|
||||
$this->last_error = '';
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if an order should be captured immediately.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function capture_authorized_downloads( Order $order ): bool {
|
||||
if (
|
||||
! $this->settings->has( 'capture_for_virtual_only' )
|
||||
|| ! $this->settings->get( 'capture_for_virtual_only' )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $order->intent() === 'CAPTURE' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* We fetch the order again as the authorize endpoint (from which the Order derives)
|
||||
* drops the item's category, making it impossible to check, if purchase units contain
|
||||
* physical goods.
|
||||
*/
|
||||
$order = $this->order_endpoint->order( $order->id() );
|
||||
|
||||
foreach ( $order->purchase_units() as $unit ) {
|
||||
if ( $unit->contains_physical_goods() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last error.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function last_error(): string {
|
||||
|
||||
return $this->last_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches a given PayPal order with a Woocommerce order.
|
||||
*
|
||||
* @param \WC_Order $wc_order The Woocommerce order.
|
||||
* @param Order $order The PayPal order.
|
||||
*
|
||||
* @return Order
|
||||
*/
|
||||
public function patch_order( \WC_Order $wc_order, Order $order ): Order {
|
||||
$updated_order = $this->order_factory->from_wc_order( $wc_order, $order );
|
||||
$order = $this->order_endpoint->patch_order_with( $order, $updated_order );
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a given order is approved.
|
||||
*
|
||||
* @param Order $order The order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function order_is_approved( Order $order ): bool {
|
||||
|
||||
if ( $order->status()->is( OrderStatus::APPROVED ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! $order->payment_source() || ! $order->payment_source()->card() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$is_approved = in_array(
|
||||
$this->threed_secure->proceed_with_order( $order ),
|
||||
array(
|
||||
ThreeDSecure::NO_DECISION,
|
||||
ThreeDSecure::PROCCEED,
|
||||
),
|
||||
true
|
||||
);
|
||||
return $is_approved;
|
||||
}
|
||||
}
|
133
modules/ppcp-wc-gateway/src/Settings/class-settings.php
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
/**
|
||||
* The settings object.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class Settings
|
||||
*/
|
||||
class Settings implements ContainerInterface {
|
||||
|
||||
public const KEY = 'woocommerce-ppcp-settings';
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $settings = array();
|
||||
|
||||
/**
|
||||
* Returns the value for an id.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws NotFoundException When nothing was found.
|
||||
*/
|
||||
public function get( $id ) {
|
||||
if ( ! $this->has( $id ) ) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
return $this->settings[ $id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a value exists.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has( $id ) {
|
||||
$this->load();
|
||||
return array_key_exists( $id, $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
* @param mixed $value The value.
|
||||
*/
|
||||
public function set( $id, $value ) {
|
||||
$this->load();
|
||||
$this->settings[ $id ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the settings to the database.
|
||||
*/
|
||||
public function persist() {
|
||||
|
||||
update_option( self::KEY, $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the onboarding.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function reset(): bool {
|
||||
$this->load();
|
||||
$fields_to_reset = array(
|
||||
'enabled',
|
||||
'dcc_gateway_enabled',
|
||||
'intent',
|
||||
'client_id',
|
||||
'client_secret',
|
||||
'merchant_email',
|
||||
);
|
||||
foreach ( $fields_to_reset as $id ) {
|
||||
$this->settings[ $id ] = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the settings.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function load(): bool {
|
||||
|
||||
if ( $this->settings ) {
|
||||
return false;
|
||||
}
|
||||
$this->settings = get_option( self::KEY, array() );
|
||||
|
||||
$defaults = array(
|
||||
'title' => __( 'PayPal', 'paypal-for-woocommerce' ),
|
||||
'description' => __(
|
||||
'Pay via PayPal.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'button_single_product_enabled' => true,
|
||||
'button_mini-cart_enabled' => true,
|
||||
'button_cart_enabled' => true,
|
||||
'brand_name' => get_bloginfo( 'name' ),
|
||||
'dcc_gateway_title' => __( 'Credit Cards', 'paypal-for-woocommerce' ),
|
||||
'dcc_gateway_description' => __(
|
||||
'Pay with your credit card.',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
);
|
||||
foreach ( $defaults as $key => $value ) {
|
||||
if ( isset( $this->settings[ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$this->settings[ $key ] = $value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
277
modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php
Normal file
|
@ -0,0 +1,277 @@
|
|||
<?php
|
||||
/**
|
||||
* Listens to requests and updates the settings if necessary.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Inpsyde\PayPalCommerce\Webhooks\WebhookRegistrar;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
/**
|
||||
* Class SettingsListener
|
||||
*/
|
||||
class SettingsListener {
|
||||
|
||||
|
||||
public const NONCE = 'ppcp-settings';
|
||||
|
||||
/**
|
||||
* The Settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* Array contains the setting fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $setting_fields;
|
||||
|
||||
/**
|
||||
* The Webhook Registrar.
|
||||
*
|
||||
* @var WebhookRegistrar
|
||||
*/
|
||||
private $webhook_registrar;
|
||||
|
||||
/**
|
||||
* The Cache.
|
||||
*
|
||||
* @var CacheInterface
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* The State.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
* @param array $setting_fields The setting fields.
|
||||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param CacheInterface $cache The Cache.
|
||||
* @param State $state The state.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
array $setting_fields,
|
||||
WebhookRegistrar $webhook_registrar,
|
||||
CacheInterface $cache,
|
||||
State $state
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->setting_fields = $setting_fields;
|
||||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the request.
|
||||
*
|
||||
* @throws \Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException When the argument was invalid.
|
||||
*/
|
||||
public function listen() {
|
||||
|
||||
if ( ! $this->is_valid_update_request() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nonce verification has been done in is_valid_update_request().
|
||||
*
|
||||
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
*/
|
||||
if ( isset( $_POST['save'] ) && sanitize_text_field( wp_unslash( $_POST['save'] ) ) === 'reset' ) {
|
||||
$this->settings->reset();
|
||||
$this->settings->persist();
|
||||
$this->webhook_registrar->unregister();
|
||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitization is done in retrieve_settings_from_raw_data().
|
||||
*
|
||||
* phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
*/
|
||||
$raw_data = ( isset( $_POST['ppcp'] ) ) ? (array) wp_unslash( $_POST['ppcp'] ) : array();
|
||||
// phpcs:enable phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$settings = $this->retrieve_settings_from_raw_data( $raw_data );
|
||||
if ( isset( $_GET['section'] ) && PayPalGateway::ID === $_GET['section'] ) {
|
||||
$settings['enabled'] = isset( $_POST['woocommerce_ppcp-gateway_enabled'] )
|
||||
&& 1 === absint( $_POST['woocommerce_ppcp-gateway_enabled'] );
|
||||
}
|
||||
if ( isset( $_GET['section'] ) && CreditCardGateway::ID === $_GET['section'] ) {
|
||||
$dcc_enabled_post_key = 'woocommerce_ppcp-credit-card-gateway_enabled';
|
||||
$settings['dcc_gateway_enabled'] = isset( $_POST[ $dcc_enabled_post_key ] )
|
||||
&& 1 === absint( $_POST[ $dcc_enabled_post_key ] );
|
||||
}
|
||||
$this->maybe_register_webhooks( $settings );
|
||||
|
||||
foreach ( $settings as $id => $value ) {
|
||||
$this->settings->set( $id, $value );
|
||||
}
|
||||
$this->settings->persist();
|
||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on the settings change, we might need to register or unregister the Webhooks at PayPal.
|
||||
*
|
||||
* @param array $settings The settings.
|
||||
*
|
||||
* @throws \Inpsyde\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasn't been found.
|
||||
*/
|
||||
private function maybe_register_webhooks( array $settings ) {
|
||||
|
||||
if ( ! $this->settings->has( 'client_id' ) && $settings['client_id'] ) {
|
||||
$this->webhook_registrar->register();
|
||||
}
|
||||
if ( $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) ) {
|
||||
$current_secret = $this->settings->has( 'client_secret' ) ?
|
||||
$this->settings->get( 'client_secret' ) : '';
|
||||
if (
|
||||
$settings['client_id'] !== $this->settings->get( 'client_id' )
|
||||
|| $settings['client_secret'] !== $current_secret
|
||||
) {
|
||||
$this->webhook_registrar->unregister();
|
||||
$this->webhook_registrar->register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the settings input data and returns a valid settings array.
|
||||
*
|
||||
* @param array $raw_data The Raw data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function retrieve_settings_from_raw_data( array $raw_data ): array {
|
||||
/**
|
||||
* Nonce verification has already been done.
|
||||
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
*/
|
||||
if ( ! isset( $_GET['section'] ) ) {
|
||||
return array();
|
||||
}
|
||||
$settings = array();
|
||||
foreach ( $this->setting_fields as $key => $config ) {
|
||||
if ( ! in_array( $this->state->current_state(), $config['screens'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
'dcc' === $config['gateway']
|
||||
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-credit-card-gateway'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
'paypal' === $config['gateway']
|
||||
&& sanitize_text_field( wp_unslash( $_GET['section'] ) ) !== 'ppcp-gateway'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
switch ( $config['type'] ) {
|
||||
case 'checkbox':
|
||||
$settings[ $key ] = isset( $raw_data[ $key ] );
|
||||
break;
|
||||
case 'text':
|
||||
case 'ppcp-text-input':
|
||||
case 'ppcp-password':
|
||||
$settings[ $key ] = isset( $raw_data[ $key ] ) ? sanitize_text_field( $raw_data[ $key ] ) : '';
|
||||
break;
|
||||
case 'password':
|
||||
if ( empty( $raw_data[ $key ] ) ) {
|
||||
break;
|
||||
}
|
||||
$settings[ $key ] = sanitize_text_field( $raw_data[ $key ] );
|
||||
break;
|
||||
case 'ppcp-multiselect':
|
||||
$values = isset( $raw_data[ $key ] ) ? (array) $raw_data[ $key ] : array();
|
||||
$values_to_save = array();
|
||||
foreach ( $values as $index => $raw_value ) {
|
||||
$value = sanitize_text_field( $raw_value );
|
||||
if ( ! in_array( $value, array_keys( $config['options'] ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
$values_to_save[] = $value;
|
||||
}
|
||||
$settings[ $key ] = $values_to_save;
|
||||
break;
|
||||
case 'select':
|
||||
$options = array_keys( $config['options'] );
|
||||
$settings[ $key ] = isset( $raw_data[ $key ] ) && in_array(
|
||||
sanitize_text_field( $raw_data[ $key ] ),
|
||||
$options,
|
||||
true
|
||||
) ? sanitize_text_field( $raw_data[ $key ] ) : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates whether the current request is supposed to update the settings.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_update_request(): bool {
|
||||
|
||||
if (
|
||||
! isset( $_REQUEST['section'] )
|
||||
|| ! in_array(
|
||||
sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ),
|
||||
array( 'ppcp-gateway', 'ppcp-credit-card-gateway' ),
|
||||
true
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
! isset( $_POST['ppcp-nonce'] )
|
||||
|| ! wp_verify_nonce(
|
||||
sanitize_text_field( wp_unslash( $_POST['ppcp-nonce'] ) ),
|
||||
self::NONCE
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
331
modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php
Normal file
|
@ -0,0 +1,331 @@
|
|||
<?php
|
||||
/**
|
||||
* Renders the settings of the Gateways.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway\Settings
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use Inpsyde\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class SettingsRenderer
|
||||
*/
|
||||
class SettingsRenderer {
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The current onboarding state.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* The setting fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $fields;
|
||||
|
||||
/**
|
||||
* Helper to see if DCC gateway can be shown.
|
||||
*
|
||||
* @var DccApplies
|
||||
*/
|
||||
private $dcc_applies;
|
||||
|
||||
/**
|
||||
* Helper to see if messages are supposed to show up.
|
||||
*
|
||||
* @var MessagesApply
|
||||
*/
|
||||
private $messages_apply;
|
||||
|
||||
/**
|
||||
* SettingsRenderer constructor.
|
||||
*
|
||||
* @param ContainerInterface $settings The Settings.
|
||||
* @param State $state The current state.
|
||||
* @param array $fields The setting fields.
|
||||
* @param DccApplies $dcc_applies Whether DCC gateway can be shown.
|
||||
* @param MessagesApply $messages_apply Whether messages can be shown.
|
||||
*/
|
||||
public function __construct(
|
||||
ContainerInterface $settings,
|
||||
State $state,
|
||||
array $fields,
|
||||
DccApplies $dcc_applies,
|
||||
MessagesApply $messages_apply
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->state = $state;
|
||||
$this->fields = $fields;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
$this->messages_apply = $messages_apply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the multiselect field.
|
||||
*
|
||||
* @param string $field The current field HTML.
|
||||
* @param string $key The current key.
|
||||
* @param array $config The configuration array.
|
||||
* @param string $value The current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_multiselect( $field, $key, $config, $value ): string {
|
||||
|
||||
if ( 'ppcp-multiselect' !== $config['type'] ) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
$options = array();
|
||||
foreach ( $config['options'] as $option_key => $option_value ) {
|
||||
$selected = ( in_array( $option_key, $value, true ) ) ? 'selected="selected"' : '';
|
||||
|
||||
$options[] = '<option value="' . esc_attr( $option_key ) . '" ' . $selected . '>' .
|
||||
esc_html( $option_value ) .
|
||||
'</option>';
|
||||
}
|
||||
|
||||
$html = sprintf(
|
||||
'<select
|
||||
multiple
|
||||
class="%s"
|
||||
name="%s"
|
||||
>%s</select>',
|
||||
esc_attr( implode( ' ', $config['class'] ) ),
|
||||
esc_attr( $key ) . '[]',
|
||||
implode( '', $options )
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the password input field.
|
||||
*
|
||||
* @param string $field The current field HTML.
|
||||
* @param string $key The current key.
|
||||
* @param array $config The configuration array.
|
||||
* @param string $value The current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_password( $field, $key, $config, $value ): string {
|
||||
|
||||
if ( 'ppcp-password' !== $config['type'] ) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
$html = sprintf(
|
||||
'<input
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
class="%s"
|
||||
name="%s"
|
||||
value="%s"
|
||||
>',
|
||||
esc_attr( implode( ' ', $config['class'] ) ),
|
||||
esc_attr( $key ),
|
||||
esc_attr( $value )
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders the text input field.
|
||||
*
|
||||
* @param string $field The current field HTML.
|
||||
* @param string $key The current key.
|
||||
* @param array $config The configuration array.
|
||||
* @param string $value The current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_text_input( $field, $key, $config, $value ): string {
|
||||
|
||||
if ( 'ppcp-text-input' !== $config['type'] ) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
$html = sprintf(
|
||||
'<input
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
class="%s"
|
||||
name="%s"
|
||||
value="%s"
|
||||
>',
|
||||
esc_attr( implode( ' ', $config['class'] ) ),
|
||||
esc_attr( $key ),
|
||||
esc_attr( $value )
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the heading field.
|
||||
*
|
||||
* @param string $field The current field HTML.
|
||||
* @param string $key The current key.
|
||||
* @param array $config The configuration array.
|
||||
* @param string $value The current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_heading( $field, $key, $config, $value ): string {
|
||||
|
||||
if ( 'ppcp-heading' !== $config['type'] ) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
$html = sprintf(
|
||||
'<h3 class="%s">%s</h3>',
|
||||
esc_attr( implode( ' ', $config['class'] ) ),
|
||||
esc_html( $config['heading'] )
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the settings.
|
||||
*
|
||||
* @param bool $is_dcc Whether it is the DCC gateway or not.
|
||||
*/
|
||||
public function render( bool $is_dcc ) {
|
||||
|
||||
$nonce = wp_create_nonce( SettingsListener::NONCE );
|
||||
?>
|
||||
<input type="hidden" name="ppcp-nonce" value="<?php echo esc_attr( $nonce ); ?>">
|
||||
<?php
|
||||
foreach ( $this->fields as $field => $config ) :
|
||||
if ( ! in_array( $this->state->current_state(), $config['screens'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $is_dcc && ! in_array( $config['gateway'], array( 'all', 'dcc' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! $is_dcc && ! in_array( $config['gateway'], array( 'all', 'paypal' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
in_array( 'dcc', $config['requirements'], true )
|
||||
&& ! $this->dcc_applies->for_country_currency()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
in_array( 'messages', $config['requirements'], true )
|
||||
&& ! $this->messages_apply->for_country()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$value = $this->settings->has( $field ) ? $this->settings->get( $field ) : null;
|
||||
$key = 'ppcp[' . $field . ']';
|
||||
$id = 'ppcp-' . $field;
|
||||
$config['id'] = $id;
|
||||
$th_td = 'ppcp-heading' !== $config['type'] ? 'td' : 'th';
|
||||
$colspan = 'ppcp-heading' !== $config['type'] ? 1 : 2;
|
||||
|
||||
?>
|
||||
<tr valign="top" id="<?php echo esc_attr( 'field-' . $field ); ?>">
|
||||
<?php if ( 'ppcp-heading' !== $config['type'] ) : ?>
|
||||
<th>
|
||||
<label
|
||||
for="<?php echo esc_attr( $id ); ?>"
|
||||
><?php echo esc_html( $config['title'] ); ?></label>
|
||||
<?php if ( isset( $config['desc_tip'] ) && $config['desc_tip'] ) : ?>
|
||||
<span
|
||||
class="woocommerce-help-tip"
|
||||
data-tip="<?php echo esc_attr( $config['description'] ); ?>"
|
||||
></span>
|
||||
<?php
|
||||
unset( $config['description'] );
|
||||
endif;
|
||||
?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
<<?php echo esc_attr( $th_td ); ?> colspan="<?php echo (int) $colspan; ?>">
|
||||
<?php
|
||||
'ppcp-text' === $config['type'] ?
|
||||
$this->render_text( $config )
|
||||
: woocommerce_form_field( $key, $config, $value );
|
||||
?>
|
||||
</<?php echo esc_attr( $th_td ); ?>>
|
||||
</tr>
|
||||
<?php
|
||||
endforeach;
|
||||
|
||||
if ( $is_dcc ) :
|
||||
?>
|
||||
<tr>
|
||||
<th><?php esc_html_e( '3D Secure', 'paypal-for-woocommerce' ); ?></th>
|
||||
<td>
|
||||
<p>
|
||||
<?php
|
||||
/**
|
||||
* We still need to provide a docs link.
|
||||
*
|
||||
* @todo: Provide link to documentation.
|
||||
*/
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
// translators: %1$s and %2$s is a link tag.
|
||||
__(
|
||||
'3D Secure benefits cardholders and merchants by providing
|
||||
an additional layer of verification using Verified by Visa,
|
||||
MasterCard SecureCode and American Express SafeKey.
|
||||
%1$sLearn more about 3D Secure.%2$s',
|
||||
'paypal-for-woocommerce'
|
||||
),
|
||||
'<a href = "#">',
|
||||
'</a>'
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the ppcp-text field given a configuration.
|
||||
*
|
||||
* @param array $config The configuration array.
|
||||
*/
|
||||
private function render_text( array $config ) {
|
||||
echo wp_kses_post( $config['text'] );
|
||||
if ( isset( $config['hidden'] ) ) {
|
||||
$value = $this->settings->has( $config['hidden'] ) ?
|
||||
(string) $this->settings->get( $config['hidden'] )
|
||||
: '';
|
||||
echo ' <input
|
||||
type = "hidden"
|
||||
name = "ppcp[' . esc_attr( $config['hidden'] ) . ']"
|
||||
value = "' . esc_attr( $value ) . '"
|
||||
> ';
|
||||
}
|
||||
}
|
||||
}
|
321
modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php
Normal file
|
@ -0,0 +1,321 @@
|
|||
<?php
|
||||
/**
|
||||
* The Gateway module.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\WcGateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\WcGateway;
|
||||
|
||||
use Dhii\Container\ServiceProvider;
|
||||
use Dhii\Modular\Module\ModuleInterface;
|
||||
use Inpsyde\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Checkout\DisableGateways;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use Interop\Container\ServiceProviderInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class WcGatewayModule
|
||||
*/
|
||||
class WcGatewayModule implements ModuleInterface {
|
||||
|
||||
/**
|
||||
* Setup the module.
|
||||
*
|
||||
* @return ServiceProviderInterface
|
||||
*/
|
||||
public function setup(): ServiceProviderInterface {
|
||||
return new ServiceProvider(
|
||||
require __DIR__ . '/../services.php',
|
||||
require __DIR__ . '/../extensions.php'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the module.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
public function run( ContainerInterface $container ) {
|
||||
$this->register_payment_gateways( $container );
|
||||
$this->register_order_functionality( $container );
|
||||
$this->register_columns( $container );
|
||||
$this->register_checkout_paypal_address_preset( $container );
|
||||
$this->ajax_gateway_enabler( $container );
|
||||
|
||||
add_filter(
|
||||
Repository::NOTICES_FILTER,
|
||||
static function ( $notices ) use ( $container ): array {
|
||||
$notice = $container->get( 'wcgateway.notice.connect' );
|
||||
/**
|
||||
* The Connect Admin Notice object.
|
||||
*
|
||||
* @var ConnectAdminNotice $notice
|
||||
*/
|
||||
$connect_message = $notice->connect_message();
|
||||
if ( $connect_message ) {
|
||||
$notices[] = $connect_message;
|
||||
}
|
||||
$authorize_order_action = $container->get( 'wcgateway.notice.authorize-order-action' );
|
||||
$authorized_message = $authorize_order_action->message();
|
||||
if ( $authorized_message ) {
|
||||
$notices[] = $authorized_message;
|
||||
}
|
||||
|
||||
return $notices;
|
||||
}
|
||||
);
|
||||
add_action(
|
||||
'woocommerce-paypal-commerce-gateway.deactivate',
|
||||
static function () use ( $container ) {
|
||||
delete_option( Settings::KEY );
|
||||
delete_option( PayPalRequestIdRepository::KEY );
|
||||
delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
|
||||
delete_option( 'woocommerce_' . CreditCardGateway::ID . '_settings' );
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
|
||||
static function () use ( $container ) {
|
||||
$endpoint = $container->get( 'wcgateway.endpoint.return-url' );
|
||||
/**
|
||||
* The Endpoint.
|
||||
*
|
||||
* @var ReturnUrlEndpoint $endpoint
|
||||
*/
|
||||
$endpoint->handle_request();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the functionality to listen to the ajax enable gateway switch.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
private function ajax_gateway_enabler( ContainerInterface $container ) {
|
||||
add_action(
|
||||
'wp_ajax_woocommerce_toggle_gateway_enabled',
|
||||
static function () use ( $container ) {
|
||||
if (
|
||||
! current_user_can( 'manage_woocommerce' )
|
||||
|| ! check_ajax_referer(
|
||||
'woocommerce-toggle-payment-gateway-enabled',
|
||||
'security'
|
||||
)
|
||||
|| ! isset( $_POST['gateway_id'] )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings $settings
|
||||
*/
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$key = PayPalGateway::ID === $_POST['gateway_id'] ? 'enabled' : '';
|
||||
if ( CreditCardGateway::ID === $_POST['gateway_id'] ) {
|
||||
$key = 'dcc_gateway_enabled';
|
||||
}
|
||||
if ( ! $key ) {
|
||||
return;
|
||||
}
|
||||
$enabled = $settings->has( $key ) ? $settings->get( $key ) : false;
|
||||
if ( ! $enabled ) {
|
||||
return;
|
||||
}
|
||||
$settings->set( $key, false );
|
||||
$settings->persist();
|
||||
},
|
||||
9
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the payment gateways.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
private function register_payment_gateways( ContainerInterface $container ) {
|
||||
|
||||
add_filter(
|
||||
'woocommerce_payment_gateways',
|
||||
static function ( $methods ) use ( $container ): array {
|
||||
$methods[] = $container->get( 'wcgateway.paypal-gateway' );
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
/**
|
||||
* The DCC Applies object.
|
||||
*
|
||||
* @var DccApplies $dcc_applies
|
||||
*/
|
||||
if ( $dcc_applies->for_country_currency() ) {
|
||||
$methods[] = $container->get( 'wcgateway.credit-card-gateway' );
|
||||
}
|
||||
return (array) $methods;
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_settings_save_checkout',
|
||||
static function () use ( $container ) {
|
||||
$listener = $container->get( 'wcgateway.settings.listener' );
|
||||
$listener->listen();
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_form_field',
|
||||
static function ( $field, $key, $args, $value ) use ( $container ) {
|
||||
$renderer = $container->get( 'wcgateway.settings.render' );
|
||||
/**
|
||||
* The Settings Renderer object.
|
||||
*
|
||||
* @var SettingsRenderer $renderer
|
||||
*/
|
||||
$field = $renderer->render_multiselect( $field, $key, $args, $value );
|
||||
$field = $renderer->render_password( $field, $key, $args, $value );
|
||||
$field = $renderer->render_text_input( $field, $key, $args, $value );
|
||||
$field = $renderer->render_heading( $field, $key, $args, $value );
|
||||
return $field;
|
||||
},
|
||||
10,
|
||||
4
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_available_payment_gateways',
|
||||
static function ( $methods ) use ( $container ): array {
|
||||
$disabler = $container->get( 'wcgateway.disabler' );
|
||||
/**
|
||||
* The Gateay disabler.
|
||||
*
|
||||
* @var DisableGateways $disabler
|
||||
*/
|
||||
return $disabler->handler( (array) $methods );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the authorize order functionality.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
private function register_order_functionality( ContainerInterface $container ) {
|
||||
add_filter(
|
||||
'woocommerce_order_actions',
|
||||
static function ( $order_actions ): array {
|
||||
$order_actions['ppcp_authorize_order'] = __(
|
||||
'Capture authorized PayPal payment',
|
||||
'paypal-for-woocommerce'
|
||||
);
|
||||
return $order_actions;
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_order_action_ppcp_authorize_order',
|
||||
static function ( \WC_Order $wc_order ) use ( $container ) {
|
||||
/**
|
||||
* The PayPal Gateway.
|
||||
*
|
||||
* @var PayPalGateway $gateway
|
||||
*/
|
||||
$gateway = $container->get( 'wcgateway.paypal-gateway' );
|
||||
$gateway->capture_authorized_payment( $wc_order );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the additional columns on the order list page.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
private function register_columns( ContainerInterface $container ) {
|
||||
add_action(
|
||||
'woocommerce_order_actions_start',
|
||||
static function ( $wc_order_id ) use ( $container ) {
|
||||
/**
|
||||
* The Payment Status Order Detail.
|
||||
*
|
||||
* @var PaymentStatusOrderDetail $class
|
||||
*/
|
||||
$class = $container->get( 'wcgateway.admin.order-payment-status' );
|
||||
$class->render( intval( $wc_order_id ) );
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'manage_edit-shop_order_columns',
|
||||
static function ( $columns ) use ( $container ) {
|
||||
/**
|
||||
* The Order Table Payment Status object.
|
||||
*
|
||||
* @var OrderTablePaymentStatusColumn $payment_status_column
|
||||
*/
|
||||
$payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||
return $payment_status_column->register( $columns );
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'manage_shop_order_posts_custom_column',
|
||||
static function ( $column, $wc_order_id ) use ( $container ) {
|
||||
/**
|
||||
* The column object.
|
||||
*
|
||||
* @var OrderTablePaymentStatusColumn $payment_status_column
|
||||
*/
|
||||
$payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||
$payment_status_column->render( $column, intval( $wc_order_id ) );
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the PayPal Address preset to overwrite Shipping in checkout.
|
||||
*
|
||||
* @param ContainerInterface $container The container.
|
||||
*/
|
||||
private function register_checkout_paypal_address_preset( ContainerInterface $container ): void {
|
||||
add_filter(
|
||||
'woocommerce_checkout_get_value',
|
||||
static function ( ...$args ) use ( $container ) {
|
||||
|
||||
/**
|
||||
* Its important to not instantiate the service too early as it
|
||||
* depends on SessionHandler and WooCommerce Session.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The CheckoutPayPalAddressPreset object.
|
||||
*
|
||||
* @var CheckoutPayPalAddressPreset $service
|
||||
*/
|
||||
$service = $container->get( 'wcgateway.checkout.address-preset' );
|
||||
|
||||
return $service->filter_checkout_field( ...$args );
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|