spree_razorpay_checkout 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e72dc88db8b53ff22661766a04c41d6a4b481d6183638de96d767983682f4c74
4
- data.tar.gz: 033dd1d5f35534ccdbecaaaa5655e21a7065563684592be0c19cd94625742f77
3
+ metadata.gz: 9fa91a572f8ba303d47dd90b0142eff75dc21478b85c9d85a9d2ca842318a4b9
4
+ data.tar.gz: 889b39cf1a9076a0b88d6d9a08d06971d4890f9fb08dbd94b4e9ba170f2d92a2
5
5
  SHA512:
6
- metadata.gz: 5e69954e3d286c3e7e6cfcacfa3866c7aca7f61eaf5097861ac4fe3d437b1da154b28e1bf1122dab2914fec8a69344111c4abb3e970048de221e7a6f38d68ad9
7
- data.tar.gz: 9206adcb915d630577fbd26b8d69a6a4465202d6dfc20c6e5e604dcd9218d200017ba087b8986179f3c87027c09665388504124babea8d6622a1a50a111a47ff
6
+ metadata.gz: f11e14acd2e4325710adc68337f10fd3d8ab3736dc5afb9d1dc91d91af5991ac3e9feaf296f337bad37ff5f469d2d4778c9dc33ecfac8314daf95766ebb9684e
7
+ data.tar.gz: 21c4b3840513e8a19987a9901d5afe1d32f18832869e876c0bc03098165ab703a55a95e101a2092403458c4e1a5314de46d2474ea786c8b69e14a3fb190ceb91
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  This Razorpay Checkout Reprository is mentioned in official [Spree Commerce Docs](https://spreecommerce.org/docs/integrations/payments/razorpay).
8
8
 
9
- ## Razorpay Extension for Spree Commerce v5
9
+ ## Razorpay Extension for Spree Commerce v5.2
10
10
  RazorPay is the only payments solution in India that allows businesses to accept, process and disburse payments with its product suite.
11
11
 
12
12
  ## Installation
@@ -59,38 +59,63 @@ RazorPay is the only payments solution in India that allows businesses to accept
59
59
  docker compose down
60
60
  docker compose up -d
61
61
  ```
62
+ ## Upgrade to Latest Version:
63
+
64
+ 1. Change version in Spree's GemFile:
65
+
66
+ ```ruby
67
+ gem "spree_razorpay_checkout", "~> 0.1.1"
68
+ ```
69
+
70
+ 2. Run Bundle Updator to Patch updated files:
71
+
72
+ ```ruby
73
+ bundle update
74
+ ```
75
+
76
+ 3. Migrate Database Tables (Recommended):
77
+
78
+ ```ruby
79
+ rails db:migrate
80
+ ```
81
+
82
+ 4. Re-Start Server (Recommended):
83
+
84
+ ```ruby
85
+ bin/rails restart
86
+ ```
62
87
 
63
88
  ## Plugin Configuration
64
- 6. Get keys from Razorpay Dashboard [here](https://dashboard.razorpay.com/app/website-app-settings/api-keys).
89
+ 1. Get keys from Razorpay Dashboard [here](https://dashboard.razorpay.com/app/website-app-settings/api-keys).
65
90
 
66
91
  <img width="1186" height="735" alt="razorpay dashboard" src="https://github.com/user-attachments/assets/f390685d-550b-4814-8785-4fcc32746f15" />
67
92
 
68
- 7. Make Sure to include both Razorpay Live & Test Keys from Razorpay Dashboard:
93
+ 2. Make Sure to include both Razorpay Live & Test Keys from Razorpay Dashboard:
69
94
 
70
95
  <img width="1121" height="736" alt="Admin Dashboard - Razorpay Plugin" src="https://github.com/user-attachments/assets/f45efc43-b1db-4c79-9ad3-e3d672014676" />
71
96
 
72
97
 
73
- 8. Drag Razorpay to Top in Payment Methods to make it Default:
98
+ 3. Drag Razorpay to Top in Payment Methods to make it Default:
74
99
 
75
100
  <img width="1121" height="726" alt="Payment Methods - Razorpay Plugin" src="https://github.com/user-attachments/assets/8e39086d-85a6-42a2-b9fb-75299044e6d6" />
76
101
 
77
102
  ## Checkout View
78
103
 
79
- 9. Checkout Page:
104
+ 4. Checkout Page:
80
105
 
81
106
  <img width="507" height="639" alt="Razorpay Checkout Page" src="https://github.com/user-attachments/assets/ddca8536-fa94-4502-96fa-4cd2219f3c17" />
82
107
 
83
- 10. Razorpay Modal to Capture Payments:
108
+ 5. Razorpay Modal to Capture Payments:
84
109
 
85
110
  <img width="767" height="728" alt="Razorpay Modal" src="https://github.com/user-attachments/assets/da83105f-8510-44ae-ac7c-28960cf3a0b3" />
86
111
 
87
- 11. Order Page (Customer View):
112
+ 6. Order Page (Customer View):
88
113
 
89
- <img width="863" height="733" alt="Razorpay in Order Page Client" src="https://github.com/user-attachments/assets/51b80fe6-4007-4223-b978-8ce65a3238de" />
114
+ <img width="940" height="648" alt="Customers Orders Page Razorpay Spree" src="https://github.com/user-attachments/assets/3361da09-9f01-4101-8c3e-de5ae94394de" />
90
115
 
91
- 12. Order Page (Admin View):
116
+ 7. Order Page (Admin View):
92
117
 
93
- <img width="820" height="543" alt="Admin Orders Page Razorpay" src="https://github.com/user-attachments/assets/6d95d1ab-83a0-4ad8-9528-353cc7315630" />
118
+ <img width="800" height="562" alt="Admin Orders Page Razorpay Spree" src="https://github.com/user-attachments/assets/895b1081-e20a-47b8-845f-ce2eb621acd7" />
94
119
 
95
120
  Thankyou for supporting this plugin. if you find any issues related to plugin you are open to contribute and support which can help more Spree users in India.
96
121
 
@@ -143,18 +168,20 @@ Thankyou for supporting this plugin. if you find any issues related to plugin yo
143
168
 
144
169
  ### Roadmap
145
170
 
146
- | **Features** | **Status** |
147
- |-----------------------------------------|------------|
148
- | Auto-Capture Order in Razorpay | Working |
149
- | Test Button for Testmode | Working |
150
- | Razorpay order creation using [OrdersAPI](https://razorpay.com/docs/payments/orders/apis/) | Working |
151
- | Fetching Total Amount in Modal | Working |
152
- | Order Creation after Payment | Working |
153
- | Razorpay Logo in Order's Page | Working |
154
- | Admin "Capture" order button | Working |
155
- | Admin side "Refund" order | Pending |
156
- | E-Mail after successful order | Pending |
157
- | Disable Pay Button for Accidental Order | Partial |
171
+ | **Features** | **Progress** | **Status** |
172
+ |-----------------------------------------------------------|--------------|------------|
173
+ | Auto-Capture Order in Razorpay | Working | ✅ |
174
+ | Test Button for Testmode | Working | ✅ |
175
+ | Razorpay order creation using [OrdersAPI](https://razorpay.com/docs/payments/orders/apis/) | Working | ✅ |
176
+ | Fetching Exact Total Amount in Modal | Working | ✅ |
177
+ | Order Creation after Successful Payment | Working | ✅ |
178
+ | Razorpay Logo in Admin/Order's Page | Working | ✅ |
179
+ | Admin side "Capture" order button | Working | ✅ |
180
+ | Admin side "Cancel" order button | Working | ✅ |
181
+ | Admin side "Refund" order button | Pending | ❌ |
182
+ | E-Mail after successful order | Working | |
183
+ | Disable Pay Button for Accidental Order | Working | ✅ |
184
+ | Razorpay Affordability Widget in Product Details Page | Upcoming | ⏳ |
158
185
 
159
186
  ### Contributing
160
187
 
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
3
+ <!-- Generator: Adobe Illustrator 29.3.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 146) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: none;
8
+ }
9
+
10
+ .st1 {
11
+ fill-rule: evenodd;
12
+ }
13
+ </style>
14
+ </defs>
15
+ <path class="st0" d="M0,0h24v24H0V0Z"/>
16
+ <g>
17
+ <path id="Fill-17" class="st1" d="M11,9.2l-.8,2.8,4.5-2.8-2.8,10.8h2.9l4.3-15.9-8,5.2Z"/>
18
+ <path id="Fill-19" class="st1" d="M6.3,15.4l-1.3,4.5h6l2.4-9.3-7.1,4.7Z"/>
19
+ </g>
20
+ </svg>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="1896px" height="401px" viewBox="0 0 1896 401" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Group</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Group">
9
+ <path d="M451.9209,151.4937 C448.9309,162.6497 443.1359,170.8377 434.5349,176.0657 C425.9239,181.2927 413.8469,183.9117 398.2689,183.9117 L348.7769,183.9117 L366.1509,119.0807 L415.6429,119.0807 C431.2089,119.0807 441.8959,121.6947 447.7019,126.9217 C453.4969,132.1547 454.9109,140.3437 451.9209,151.4937 M503.1739,150.0967 C509.4679,126.6377 506.8589,108.6267 495.3509,96.0797 C483.8409,83.5327 463.6739,77.2627 434.8709,77.2627 L324.3909,77.2627 L257.8969,325.4027 L311.5719,325.4027 L338.3809,225.3777 L373.5809,225.3777 C381.4739,225.3777 387.6869,226.6577 392.2309,229.2137 C396.7849,231.7747 399.4509,236.3067 400.2739,242.8037 L409.8479,325.4027 L467.3589,325.4027 L458.0289,248.3847 C456.1279,231.1897 448.2589,221.0827 434.4309,218.0637 C452.0599,212.9577 466.8259,204.4677 478.7179,192.6167 C490.5989,180.7717 498.7579,166.6017 503.1739,150.0967" id="Fill-1" fill="#072654"></path>
10
+ <path d="M633.625,236.533 C629.14,253.258 622.231,266.042 612.901,274.868 C603.56,283.7 592.386,288.111 579.382,288.111 C566.122,288.111 557.128,283.758 552.387,275.042 C547.623,266.332 547.461,253.733 551.889,237.228 C556.305,220.735 563.352,207.841 573.053,198.539 C582.742,189.255 594.09,184.602 607.105,184.602 C620.11,184.602 628.919,189.082 633.485,198.024 C638.053,206.966 638.11,219.802 633.625,236.533 L633.625,236.533 Z M657.153,148.706 L650.431,173.8 C647.521,164.736 641.9,157.538 633.578,152.195 C625.245,146.852 614.918,144.174 602.608,144.174 C587.506,144.174 572.983,148.069 559.052,155.852 C545.12,163.64 532.938,174.617 522.519,188.786 C512.099,202.961 504.461,219.107 499.604,237.228 C494.748,255.356 493.774,271.328 496.695,285.149 C499.616,298.977 505.944,309.605 515.691,317.04 C525.428,324.481 537.969,328.19 553.303,328.19 C565.612,328.19 577.342,325.635 588.469,320.523 C599.595,315.418 609.041,308.325 616.818,299.266 L609.807,325.403 L661.731,325.403 L709.079,148.706 L657.153,148.706 Z" id="Fill-3" fill="#072654"></path>
11
+ <polygon id="Fill-5" fill="#072654" points="895.79 148.7061 744.882 148.7061 734.334 188.0911 822.155 188.0911 706.042 288.4581 696.132 325.4031 851.92 325.4031 862.478 286.0241 768.388 286.0241 886.263 184.2541"></polygon>
12
+ <path d="M1028.6514,236.1853 C1023.9804,253.6053 1017.0604,266.6273 1007.9044,275.2223 C998.7484,283.8163 987.6674,288.1103 974.6634,288.1103 C947.4714,288.1103 938.5234,270.8113 947.7964,236.1853 C952.4094,218.9903 959.3634,206.0383 968.6594,197.3283 C977.9654,188.6123 989.2324,184.2543 1002.4804,184.2543 C1015.4844,184.2543 1024.2584,188.6123 1028.7794,197.3283 C1033.2984,206.0383 1033.2644,218.9903 1028.6514,236.1853 M1059.0304,155.3243 C1047.0804,147.8943 1031.8154,144.1743 1013.2244,144.1743 C994.4014,144.1743 976.9694,147.8943 960.9174,155.3243 C944.8644,162.7653 931.1984,173.4523 919.9214,187.3893 C908.6314,201.3323 900.4954,217.5943 895.5114,236.1853 C890.5274,254.7763 889.9484,271.0323 893.7734,284.9753 C897.5864,298.9183 905.5144,309.6053 917.5914,317.0403 C929.6574,324.4813 945.0954,328.1903 963.9194,328.1903 C982.5094,328.1903 999.7674,324.4813 1015.7054,317.0403 C1031.6184,309.6053 1045.2374,298.9183 1056.5264,284.9753 C1067.8034,271.0323 1075.9404,254.7763 1080.9244,236.1853 C1085.9084,217.5943 1086.4884,201.3323 1082.6744,187.3893 C1078.8494,173.4523 1070.9674,162.7653 1059.0304,155.3243" id="Fill-7" fill="#072654"></path>
13
+ <path d="M1602.1367,236.533 C1597.6517,253.258 1590.7427,266.042 1581.4127,274.868 C1572.0817,283.7 1560.8857,288.111 1547.8817,288.111 C1534.6457,288.111 1525.6397,283.758 1520.8987,275.042 C1516.1347,266.332 1515.9727,253.733 1520.4007,237.228 C1524.8167,220.735 1531.8637,207.841 1541.5647,198.539 C1551.2537,189.255 1562.6017,184.602 1575.6167,184.602 C1588.6217,184.602 1597.4307,189.082 1601.9967,198.024 C1606.5647,206.966 1606.6217,219.802 1602.1367,236.533 L1602.1367,236.533 Z M1625.6647,148.706 L1618.9427,173.8 C1616.0327,164.736 1610.4117,157.538 1602.0897,152.195 C1593.7567,146.852 1583.4297,144.174 1571.1197,144.174 C1556.0177,144.174 1541.4947,148.069 1527.5637,155.852 C1513.6317,163.64 1501.4497,174.617 1491.0307,188.786 C1480.6107,202.961 1472.9717,219.107 1468.1157,237.228 C1463.2597,255.356 1462.2967,271.328 1465.2067,285.149 C1468.1267,298.977 1474.4447,309.605 1484.2027,317.04 C1493.9397,324.481 1506.4807,328.19 1521.8147,328.19 C1534.1227,328.19 1545.8537,325.635 1556.9797,320.523 C1568.1067,315.418 1577.5527,308.325 1585.3297,299.266 L1578.3187,325.403 L1630.2427,325.403 L1677.5907,148.706 L1625.6647,148.706 Z" id="Fill-9" fill="#072654"></path>
14
+ <path d="M1244.165,196.1055 L1257.401,148.0105 C1252.904,145.6865 1246.946,144.5225 1239.517,144.5225 C1227.66,144.5225 1216.243,147.4835 1205.244,153.4115 C1195.798,158.4975 1187.754,165.6365 1180.962,174.5815 L1187.847,148.6815 L1172.813,148.7065 L1135.938,148.7065 L1088.227,325.4025 L1140.87,325.4025 L1165.616,233.0505 C1169.221,219.5765 1175.688,209.0635 1185.042,201.5125 C1194.372,193.9615 1206.02,190.1825 1219.964,190.1825 C1228.563,190.1825 1236.619,192.1585 1244.165,196.1055" id="Fill-11" fill="#072654"></path>
15
+ <path d="M1390.6973,237.2256 C1386.2693,253.7306 1379.4083,266.3296 1370.1123,275.0396 C1360.7943,283.7556 1349.6433,288.1076 1336.6393,288.1076 C1323.6233,288.1076 1314.7573,283.6976 1310.0393,274.8656 C1305.3103,266.0396 1305.1943,253.2606 1309.6793,236.5296 C1314.1653,219.7996 1321.1423,206.9626 1330.6243,198.0206 C1340.1043,189.0786 1351.3593,184.5986 1364.3753,184.5986 C1377.1473,184.5986 1385.8293,189.2526 1390.4303,198.5426 C1395.0203,207.8376 1395.1133,220.7376 1390.6973,237.2256 M1427.4853,155.8486 C1417.7153,148.0656 1405.2783,144.1776 1390.1873,144.1776 C1376.9393,144.1776 1364.3293,147.1966 1352.3903,153.2356 C1340.4183,159.2856 1330.7173,167.5206 1323.2753,177.9806 L1323.4433,176.8216 L1332.2873,148.6786 L1322.1103,148.6786 L1322.1103,148.7036 L1280.9003,148.7036 L1267.8153,197.5656 C1267.6643,198.1336 1267.5373,198.6636 1267.3853,199.2376 L1213.4093,400.6806 L1266.0423,400.6806 L1293.2213,299.2696 C1295.8863,308.3216 1301.4273,315.4146 1309.8193,320.5206 C1318.2103,325.6316 1328.5603,328.1876 1340.8813,328.1876 C1356.2163,328.1876 1370.7963,324.4786 1384.6463,317.0376 C1398.4863,309.6076 1410.5163,298.9736 1420.7173,285.1466 C1430.9273,271.3306 1438.4623,255.3526 1443.3183,237.2256 C1448.1753,219.1036 1449.1823,202.9586 1446.3663,188.7836 C1443.5503,174.6136 1437.2443,163.6376 1427.4853,155.8486" id="Fill-13" fill="#072654"></path>
16
+ <path d="M1895.5381,148.7554 L1895.5721,148.7064 L1863.6921,148.7064 C1862.6731,148.7064 1861.7741,148.7354 1860.8421,148.7554 L1844.2961,148.7554 L1835.8351,160.5434 C1835.1571,161.4314 1834.4791,162.3254 1833.7491,163.3624 L1832.8271,164.7274 L1765.5851,258.3754 L1751.6421,148.7064 L1696.5641,148.7064 L1724.4561,315.3544 L1662.8591,400.6834 L1664.6151,400.6834 L1696.0651,400.6834 L1717.7341,400.6834 L1732.6621,379.5374 C1733.1021,378.9074 1733.4791,378.3914 1733.9491,377.7254 L1751.3691,353.0284 L1751.8681,352.3214 L1829.8131,241.8274 L1895.4851,148.8284 L1895.5721,148.7554 L1895.5381,148.7554 Z" id="Fill-15" fill="#072654"></path>
17
+ <polygon id="Fill-17" fill="#3395FF" points="122.6338 105.6902 106.8778 163.6732 197.0338 105.3642 138.0748 325.3482 197.9478 325.4032 285.0458 0.4822"></polygon>
18
+ <path d="M25.5947,232.9246 L0.8077,325.4026 L123.5337,325.4026 C123.5337,325.4026 173.7317,137.3196 173.7457,137.2656 C173.6987,137.2956 25.5947,232.9246 25.5947,232.9246" id="Fill-19" fill="#072654"></path>
19
+ </g>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 1896 401">
3
+ <!-- Generator: Adobe Illustrator 29.3.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 146) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #fff;
8
+ }
9
+
10
+ .st0, .st1 {
11
+ fill-rule: evenodd;
12
+ }
13
+
14
+ .st1 {
15
+ fill: #3395ff;
16
+ }
17
+ </style>
18
+ </defs>
19
+ <g id="Page-1">
20
+ <g id="Group">
21
+ <path id="Fill-1" class="st0" d="M451.9,151.5c-3,11.2-8.8,19.3-17.4,24.6-8.6,5.2-20.7,7.8-36.3,7.8h-49.5l17.4-64.8h49.5c15.6,0,26.3,2.6,32.1,7.8,5.8,5.2,7.2,13.4,4.2,24.6M503.2,150.1c6.3-23.5,3.7-41.5-7.8-54-11.5-12.5-31.7-18.8-60.5-18.8h-110.5l-66.5,248.1h53.7l26.8-100h35.2c7.9,0,14.1,1.3,18.6,3.8,4.6,2.6,7.2,7.1,8,13.6l9.6,82.6h57.5l-9.3-77c-1.9-17.2-9.8-27.3-23.6-30.3,17.6-5.1,32.4-13.6,44.3-25.4,11.9-11.8,20-26,24.5-42.5"/>
22
+ <path id="Fill-3" class="st0" d="M633.6,236.5c-4.5,16.7-11.4,29.5-20.7,38.3-9.3,8.8-20.5,13.2-33.5,13.2s-22.3-4.4-27-13.1c-4.8-8.7-4.9-21.3-.5-37.8,4.4-16.5,11.5-29.4,21.2-38.7,9.7-9.3,21-13.9,34.1-13.9s21.8,4.5,26.4,13.4c4.6,8.9,4.6,21.8.1,38.5h0ZM657.2,148.7l-6.7,25.1c-2.9-9.1-8.5-16.3-16.9-21.6-8.3-5.3-18.7-8-31-8s-29.6,3.9-43.6,11.7c-13.9,7.8-26.1,18.8-36.5,32.9-10.4,14.2-18.1,30.3-22.9,48.4-4.9,18.1-5.8,34.1-2.9,47.9,2.9,13.8,9.2,24.5,19,31.9,9.7,7.4,22.3,11.1,37.6,11.1s24-2.6,35.2-7.7c11.1-5.1,20.6-12.2,28.3-21.3l-7,26.1h51.9l47.3-176.7h-51.9Z"/>
23
+ <polygon id="Fill-5" class="st0" points="895.8 148.7 744.9 148.7 734.3 188.1 822.2 188.1 706 288.5 696.1 325.4 851.9 325.4 862.5 286 768.4 286 886.3 184.3 895.8 148.7"/>
24
+ <path id="Fill-7" class="st0" d="M1028.7,236.2c-4.7,17.4-11.6,30.4-20.7,39-9.2,8.6-20.2,12.9-33.2,12.9-27.2,0-36.1-17.3-26.9-51.9,4.6-17.2,11.6-30.1,20.9-38.9,9.3-8.7,20.6-13.1,33.8-13.1s21.8,4.4,26.3,13.1c4.5,8.7,4.5,21.7-.1,38.9M1059,155.3c-11.9-7.4-27.2-11.1-45.8-11.1s-36.3,3.7-52.3,11.1c-16.1,7.4-29.7,18.1-41,32.1-11.3,13.9-19.4,30.2-24.4,48.8s-5.6,34.8-1.7,48.8c3.8,13.9,11.7,24.6,23.8,32.1,12.1,7.4,27.5,11.1,46.3,11.1s35.8-3.7,51.8-11.1c15.9-7.4,29.5-18.1,40.8-32.1,11.3-13.9,19.4-30.2,24.4-48.8s5.6-34.9,1.8-48.8c-3.8-13.9-11.7-24.6-23.6-32.1"/>
25
+ <path id="Fill-9" class="st0" d="M1602.1,236.5c-4.5,16.7-11.4,29.5-20.7,38.3-9.3,8.8-20.5,13.2-33.5,13.2s-22.2-4.4-27-13.1c-4.8-8.7-4.9-21.3-.5-37.8,4.4-16.5,11.5-29.4,21.2-38.7,9.7-9.3,21-13.9,34.1-13.9s21.8,4.5,26.4,13.4c4.6,8.9,4.6,21.8.1,38.5h0ZM1625.7,148.7l-6.7,25.1c-2.9-9.1-8.5-16.3-16.9-21.6-8.3-5.3-18.7-8-31-8s-29.6,3.9-43.6,11.7c-13.9,7.8-26.1,18.8-36.5,32.9-10.4,14.2-18.1,30.3-22.9,48.4-4.9,18.1-5.8,34.1-2.9,47.9,2.9,13.8,9.2,24.5,19,31.9,9.7,7.4,22.3,11.1,37.6,11.1s24-2.6,35.2-7.7c11.1-5.1,20.6-12.2,28.3-21.3l-7,26.1h51.9l47.3-176.7h-51.9Z"/>
26
+ <path id="Fill-11" class="st0" d="M1244.2,196.1l13.2-48.1c-4.5-2.3-10.5-3.5-17.9-3.5-11.9,0-23.3,3-34.3,8.9-9.4,5.1-17.5,12.2-24.3,21.2l6.9-25.9h-15s-36.9,0-36.9,0l-47.7,176.7h52.6l24.7-92.4c3.6-13.5,10.1-24,19.4-31.5,9.3-7.6,21-11.3,34.9-11.3s16.7,2,24.2,5.9"/>
27
+ <path id="Fill-13" class="st0" d="M1390.7,237.2c-4.4,16.5-11.3,29.1-20.6,37.8-9.3,8.7-20.5,13.1-33.5,13.1s-21.9-4.4-26.6-13.2c-4.7-8.8-4.8-21.6-.4-38.3,4.5-16.7,11.5-29.6,20.9-38.5,9.5-8.9,20.7-13.4,33.8-13.4s21.5,4.7,26.1,13.9c4.6,9.3,4.7,22.2.3,38.7M1427.5,155.8c-9.8-7.8-22.2-11.7-37.3-11.7s-25.9,3-37.8,9.1c-12,6.1-21.7,14.3-29.1,24.7l.2-1.2,8.8-28.1h-10.2s-41.2,0-41.2,0l-13.1,48.9c-.2.6-.3,1.1-.4,1.7l-54,201.4h52.6l27.2-101.4c2.7,9.1,8.2,16.1,16.6,21.3,8.4,5.1,18.7,7.7,31.1,7.7s29.9-3.7,43.8-11.1c13.8-7.4,25.9-18.1,36.1-31.9,10.2-13.8,17.7-29.8,22.6-47.9,4.9-18.1,5.9-34.3,3-48.4-2.8-14.2-9.1-25.1-18.9-32.9"/>
28
+ <path id="Fill-15" class="st0" d="M1895.5,148.8h0s-31.9,0-31.9,0c-1,0-1.9,0-2.9,0h-16.5l-8.5,11.8c-.7.9-1.4,1.8-2.1,2.8l-.9,1.4-67.2,93.6-13.9-109.7h-55.1l27.9,166.6-61.6,85.3h54.9l14.9-21.1c.4-.6.8-1.1,1.3-1.8l17.4-24.7.5-.7,77.9-110.5,65.7-93h0c0,0,0,0,0,0Z"/>
29
+ <polygon id="Fill-17" class="st1" points="122.6 105.7 106.9 163.7 197 105.4 138.1 325.3 197.9 325.4 285 .5 122.6 105.7"/>
30
+ <path id="Fill-19" class="st0" d="M25.6,232.9L.8,325.4h122.7s50.2-188.1,50.2-188.1c0,0-148.2,95.7-148.2,95.7"/>
31
+ </g>
32
+ </g>
33
+ </svg>
@@ -0,0 +1,29 @@
1
+ <svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 232.55 132.88" width="160" height="160">
2
+ <defs>
3
+ <style>
4
+ .cls-1 {
5
+ stroke-miterlimit: 10;
6
+ }
7
+ .cls-1, .cls-2 {
8
+ fill: none;
9
+ stroke: #bababa;
10
+ stroke-linecap: round;
11
+ stroke-width: 3px;
12
+ }
13
+ .cls-3 {
14
+ fill: #bababa;
15
+ }
16
+ .cls-2 {
17
+ stroke-linejoin: round;
18
+ }
19
+ </style>
20
+ </defs>
21
+ <g id="Layer_1-2" data-name="Layer 1">
22
+ <polyline class="cls-1" points="1.5 18.16 203.71 18.16 203.71 65.59"/>
23
+ <polyline class="cls-2" points="171.76 72.65 231.05 72.65 225.69 65.59 231.05 72.65 225.69 79.71"/>
24
+ <circle class="cls-3" cx="9.57" cy="10.07" r="2.95"/>
25
+ <circle class="cls-3" cx="18.79" cy="10.07" r="2.95"/>
26
+ <circle class="cls-3" cx="27.84" cy="10.07" r="2.95"/>
27
+ <path class="cls-1" d="m203.71,18.16V4.81c0-1.83-1.48-3.31-3.31-3.31H4.81c-1.83,0-3.31,1.48-3.31,3.31v123.27c0,1.83,1.48,3.31,3.31,3.31h195.59c1.83,0,3.31-1.48,3.31-3.31v-48.36"/>
28
+ </g>
29
+ </svg>
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module ProductsControllerDecorator
3
+ def self.prepended(base)
4
+ base.before_action :force_razorpay_view_priority
5
+ end
6
+
7
+ private
8
+
9
+ def force_razorpay_view_priority
10
+ plugin_theme_path = SpreeRazorpayCheckout::Engine.root.join('app', 'views', 'themes', 'default')
11
+ prepend_view_path(plugin_theme_path)
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ ::Spree::ProductsController.prepend(Spree::ProductsControllerDecorator)
@@ -4,11 +4,17 @@ module Spree
4
4
 
5
5
  include Spree::RazorPay
6
6
 
7
- # Step 1: Create Razorpay Order (Kept from the "New" version for security)
7
+ # Step 1: Create Razorpay Order
8
8
  def create_order
9
9
  order = Spree::Order.find_by(id: params[:order_id])
10
+ order&.reload
11
+
10
12
  return render json: { success: false, error: 'Order not found' }, status: :not_found unless order
11
13
 
14
+ if order.outstanding_balance <= 0
15
+ return render json: { success: false, error: "Order is already paid" }, status: :unprocessable_entity
16
+ end
17
+
12
18
  razorpay_order_id, amount = ::Razorpay::RpOrder::Api.new.create(order.id)
13
19
 
14
20
  if razorpay_order_id.present?
@@ -20,43 +26,29 @@ module Spree
20
26
 
21
27
  # Step 2: Handle Response
22
28
  def razor_response
23
- # 1. Find the Order
24
29
  order = Spree::Order.find_by(number: params[:order_id] || params[:order_number])
25
30
  unless order
26
31
  flash[:error] = "Order not found."
27
32
  return redirect_to checkout_state_path(:payment)
28
33
  end
29
34
 
30
- # 2. Verify Signature
31
35
  unless valid_signature?
32
36
  flash[:error] = "Payment signature verification failed."
33
37
  return redirect_to checkout_state_path(order.state)
34
38
  end
35
39
 
36
40
  begin
37
- # 3. Capture and Verify Payment on Razorpay
38
41
  razorpay_payment = gateway.verify_and_capture_razorpay_payment(order, razorpay_payment_id)
39
-
40
- # 4. Create Spree Payment Record
41
42
  spree_payment = order.razor_payment(razorpay_payment, payment_method, params[:razorpay_signature])
42
43
 
43
- # 5. FORCE COMPLETE THE PAYMENT
44
- # This ensures the payment is marked 'completed' immediately
45
- if spree_payment.respond_to?(:complete!)
44
+ if razorpay_payment.status == 'captured'
46
45
  spree_payment.complete!
46
+ elsif razorpay_payment.status == 'authorized'
47
+ spree_payment.pend!
47
48
  end
48
-
49
- # 6. Advance Order State
50
- # Keep calling next! until the order is fully finalized
51
49
  while !order.completed?
52
50
  order.next!
53
51
  end
54
-
55
- # 7. Force update payment state to 'paid'
56
- order.update(payment_state: 'paid') if order.respond_to?(:payment_state)
57
-
58
- # 8. Redirect to the specific Token URL
59
- #flash['order_completed'] = true
60
52
  redirect_to completion_route
61
53
 
62
54
  rescue StandardError => e
@@ -105,14 +97,11 @@ module Spree
105
97
  end
106
98
 
107
99
  def completion_route
108
- # Retrieve the guest token (supports both old and new Spree versions)
109
100
  token = order.respond_to?(:guest_token) ? order.guest_token : order.token
110
101
 
111
102
  if token.present?
112
- # Manually construct the URL: /checkout/TOKEN/complete
113
103
  "/checkout/#{token}/complete"
114
104
  else
115
- # Fallback if no token exists (standard logged-in user path)
116
105
  spree.order_path(order)
117
106
  end
118
107
  end
@@ -123,7 +123,7 @@ module Spree
123
123
  payment = Razorpay::Payment.fetch(razorpay_payment_id)
124
124
  # If payment is not captured and auto_capture set true, capture it
125
125
  if payment.status == 'authorized'
126
- amount = (order.total.to_f * 100).to_i
126
+ amount = order.inr_amt_in_paise
127
127
  payment = payment.capture(amount: amount)
128
128
  end
129
129
 
@@ -0,0 +1,79 @@
1
+ module Spree
2
+ module PageBlocks
3
+ module Products
4
+ class RazorpayAffordability < Spree::PageBlock
5
+ # Key / fallback
6
+ preference :merchant_key_id, :string
7
+ preference :fallback_amount, :integer, default: 50000
8
+
9
+ # Appearance & Color (header/theme + heading + content + discount + link/button + footer + darkmode)
10
+ preference :theme_color, :string, default: '#800080' # header theme color
11
+ preference :heading_color, :string, default: '#000000'
12
+ preference :heading_font_size, :integer, default: 14 # px
13
+
14
+ preference :content_background_color, :string, default: '#ffffff'
15
+ preference :content_color, :string, default: '#000000'
16
+ preference :content_font_size, :integer, default: 13 # px
17
+
18
+ preference :discount_color, :string, default: '#e60099'
19
+
20
+ # link/button
21
+ preference :link_button, :boolean, default: true
22
+ preference :link_color, :string, default: '#000000'
23
+ preference :link_font_size, :integer, default: 12 # px
24
+
25
+ # footer
26
+ preference :footer_color, :string, default: '#000000'
27
+ preference :footer_font_size, :integer, default: 12 # px
28
+ preference :footer_dark_logo, :boolean, default: false
29
+
30
+ # dark mode
31
+ preference :is_dark_mode, :boolean, default: false
32
+
33
+ # Widget settings toggles
34
+ preference :offers_enabled, :boolean, default: true
35
+ preference :emi_enabled, :boolean, default: true
36
+ preference :cardless_emi_enabled, :boolean, default: true
37
+ preference :paylater_enabled, :boolean, default: true
38
+
39
+ # expose names & metadata for admin (optional helper methods)
40
+ def self.block_name
41
+ "Razorpay Affordability Widget"
42
+ end
43
+
44
+ def self.display_name
45
+ "Razorpay Affordability"
46
+ end
47
+
48
+ def icon_name
49
+ "hexagon-letter-r"
50
+ end
51
+
52
+ def render(view_context, locals = {})
53
+ Rails.logger.info "🎯 RazorpayAffordability#render called for block ID: #{id}"
54
+ if respond_to?(:available?, true)
55
+ is_available = available?(locals)
56
+ Rails.logger.info " Available check: #{is_available}"
57
+ unless is_available
58
+ Rails.logger.warn " ⚠️ Block marked as not available, but rendering anyway"
59
+ end
60
+ end
61
+
62
+ begin
63
+ Rails.logger.info " Rendering partial: spree/page_blocks/products/razorpay_affordability/razorpay_affordability"
64
+ result = view_context.render partial: 'spree/page_blocks/products/razorpay_affordability/razorpay_affordability',
65
+ locals: locals.merge(block: self, page_block: self)
66
+ Rails.logger.info " ✅ Render successful, output length: #{result.to_s.length}"
67
+ result
68
+ rescue ActionView::MissingTemplate => e
69
+ Rails.logger.error " ❌ Missing template: #{e.message}"
70
+ ''
71
+ rescue => e
72
+ Rails.logger.error " ❌ Error rendering Razorpay Affordability block: #{e.message}"
73
+ "<div class='razorpay-affordability-error'>Error loading Razorpay Affordability Widget</div>".html_safe
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module PageSections
3
+ module ProductDetailsDecorator
4
+ def default_blocks
5
+ super + [Spree::PageBlocks::Products::RazorpayAffordability.new]
6
+ end
7
+
8
+ def available_blocks_to_add
9
+ super + [Spree::PageBlocks::Products::RazorpayAffordability]
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Spree::PageSections::ProductDetails.prepend(
16
+ Spree::PageSections::ProductDetailsDecorator
17
+ )
18
+
@@ -4,16 +4,14 @@ module Spree
4
4
 
5
5
  belongs_to :order, class_name: 'Spree::Order', optional: true
6
6
 
7
- # Appears in Spree Admin > Payments
8
7
  def name
9
- "Razorpay"
8
+ "Razorpay Secure (UPI, Wallets, Cards & Netbanking)"
10
9
  end
11
10
 
12
11
  def method_type
13
12
  "razorpay"
14
13
  end
15
14
 
16
- # Optional — to show the payment IDs in admin
17
15
  def payment_id
18
16
  self.razorpay_payment_id
19
17
  end
@@ -1,12 +1,34 @@
1
1
  module SpreeRazorpayCheckout
2
2
  module Spree
3
3
  module OrderDecorator
4
+
4
5
  def inr_amt_in_paise
5
- (total.to_f * 100).to_i
6
+ payments.reload
7
+
8
+ prepaid_amount = payments.select do |p|
9
+ valid_state = %w[checkout pending processing completed].include?(p.state)
10
+
11
+ not_razorpay = !p.source_type.to_s.include?('RazorpayCheckout') &&
12
+ !p.payment_method&.type.to_s.include?('RazorpayGateway')
13
+
14
+ valid_state && not_razorpay
15
+ end.sum(&:amount)
16
+
17
+ amount_needed = total - prepaid_amount
18
+
19
+ Rails.logger.info "Razorpay Calc: Total=#{total}, Prepaid=#{prepaid_amount}, Needed=#{amount_needed}"
20
+
21
+ return 0 if amount_needed <= 0
22
+
23
+ (amount_needed.to_f * 100).to_i
6
24
  end
7
25
 
8
- # Create a Spree::Payment and return it so controller can complete it
9
26
  def razor_payment(payment_object, payment_method, razorpay_signature)
27
+
28
+ amount_to_charge = (inr_amt_in_paise / 100.0)
29
+
30
+ amount_to_charge = total if amount_to_charge <= 0
31
+
10
32
  source = ::Spree::RazorpayCheckout.create!(
11
33
  order_id: id,
12
34
  razorpay_payment_id: payment_object.id,
@@ -25,7 +47,7 @@ module SpreeRazorpayCheckout
25
47
  payment = payments.create!(
26
48
  source: source,
27
49
  payment_method: payment_method,
28
- amount: total,
50
+ amount: amount_to_charge,
29
51
  response_code: payment_object.id
30
52
  )
31
53
 
@@ -6,27 +6,29 @@ module Razorpay
6
6
  def create(order_id)
7
7
  @order = Spree::Order.find_by(id: order_id)
8
8
  raise "Order not found" unless order
9
-
10
- razorpay_order = Razorpay::Order.create(order_create_params)
11
-
9
+ params = order_create_params
10
+ Rails.logger.info "Razorpay::Order.create Params: #{params.inspect}"
11
+ razorpay_order = Razorpay::Order.create(params)
12
12
  if razorpay_order.try(:id).present?
13
13
  log_order_in_db(razorpay_order.id)
14
- return [razorpay_order.id, order.inr_amt_in_paise]
14
+ return [razorpay_order.id, params[:amount]]
15
15
  end
16
-
17
16
  ['', 0]
18
17
  rescue StandardError => e
19
18
  Rails.logger.error("Razorpay Order create failed: #{e.message}")
19
+ Rails.logger.error(e.backtrace.join("\n"))
20
20
  ['', 0]
21
21
  end
22
22
 
23
23
  private
24
24
 
25
25
  def order_create_params
26
+ amt = order.inr_amt_in_paise
26
27
  {
27
- amount: order.inr_amt_in_paise,
28
- currency: order.currency || 'INR',
29
- receipt: order.number
28
+ amount: amt.to_i,
29
+ currency: (order.currency || 'INR').to_s,
30
+ receipt: order.number.to_s,
31
+ payment_capture: 1
30
32
  }
31
33
  end
32
34