Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit fc00841

Browse files
committed
merge main to feature branch
2 parents 12bb4d4 + 3e5049d commit fc00841

10 files changed

Lines changed: 322 additions & 0 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.zenfulcode.commercify.commercify.api.requests;
2+
3+
public record CapturePaymentRequest(double captureAmount, boolean isPartialCapture) {
4+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.zenfulcode.commercify.commercify.api.requests;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import lombok.Builder;
6+
7+
@Builder
8+
@JsonIgnoreProperties(ignoreUnknown = true)
9+
public record WebhookPayload(
10+
@JsonProperty("msn") String msn,
11+
@JsonProperty("reference") String reference,
12+
@JsonProperty("pspReference") String pspReference,
13+
@JsonProperty("name") String name,
14+
@JsonProperty("amount") Object amount,
15+
@JsonProperty("timestamp") String timestamp,
16+
@JsonProperty("idempotencyKey") String idempotencyKey,
17+
@JsonProperty("success") boolean success
18+
) {
19+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.zenfulcode.commercify.commercify.config;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.mail.javamail.JavaMailSender;
7+
import org.springframework.mail.javamail.JavaMailSenderImpl;
8+
9+
import java.util.Properties;
10+
11+
@Configuration
12+
public class MailConfig {
13+
@Value("${spring.mail.username}")
14+
private String username;
15+
@Value("${spring.mail.password}")
16+
private String password;
17+
@Value("${spring.mail.host}")
18+
private String host;
19+
@Value("${spring.mail.port}")
20+
private int port;
21+
22+
@Value("${spring.mail.properties.mail.smtp.starttls.enable}")
23+
private boolean tls = true;
24+
@Value("${spring.mail.properties.mail.smtp.auth}")
25+
private boolean auth = true;
26+
27+
@Bean
28+
public JavaMailSender getJavaMailSender() {
29+
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
30+
mailSender.setHost(host);
31+
mailSender.setPort(port);
32+
33+
mailSender.setUsername(username);
34+
mailSender.setPassword(password);
35+
36+
Properties props = mailSender.getJavaMailProperties();
37+
props.put("mail.transport.protocol", "smtp");
38+
props.put("mail.smtp.auth", auth);
39+
props.put("mail.smtp.starttls.enable", tls);
40+
props.put("mail.debug", "false");
41+
42+
return mailSender;
43+
}
44+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.zenfulcode.commercify.commercify.entity;
2+
3+
import jakarta.persistence.*;
4+
import lombok.*;
5+
import org.hibernate.annotations.CreationTimestamp;
6+
import org.hibernate.annotations.UpdateTimestamp;
7+
8+
import java.time.Instant;
9+
10+
@Entity
11+
@Table(name = "webhook_configs")
12+
@Getter
13+
@Setter
14+
@Builder
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
public class WebhookConfigEntity {
18+
@Id
19+
@GeneratedValue(strategy = GenerationType.IDENTITY)
20+
private Long id;
21+
22+
@Column(name = "provider", nullable = false)
23+
private String provider;
24+
25+
@Column(name = "webhook_url", nullable = false)
26+
private String webhookUrl;
27+
28+
@Column(name = "webhook_secret", nullable = false)
29+
private String webhookSecret;
30+
31+
@Column(name = "created_at", nullable = false)
32+
@CreationTimestamp
33+
private Instant createdAt;
34+
35+
@Column(name = "updated_at")
36+
@UpdateTimestamp
37+
private Instant updatedAt;
38+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.zenfulcode.commercify.commercify.integration;
2+
3+
public record WebhookRegistrationResponse(
4+
String secret,
5+
String id
6+
) {
7+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.zenfulcode.commercify.commercify.integration;
2+
3+
public record WebhookSubscribeRequest(String callbackUrl) {
4+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.zenfulcode.commercify.commercify.repository;
2+
3+
import com.zenfulcode.commercify.commercify.entity.WebhookConfigEntity;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.Optional;
8+
9+
@Repository
10+
public interface WebhookConfigRepository extends JpaRepository<WebhookConfigEntity, Long> {
11+
Optional<WebhookConfigEntity> findByProvider(String provider);
12+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
6+
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.30.xsd"
7+
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS">
8+
<changeSet id="1736341443519-1" author="gkhaavik">
9+
<createTable tableName="webhook_configs">
10+
<column autoIncrement="true" name="id" type="BIGINT">
11+
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_webhook_configs"/>
12+
</column>
13+
<column name="provider" type="VARCHAR(255)">
14+
<constraints nullable="false"/>
15+
</column>
16+
<column name="webhook_url" type="VARCHAR(255)">
17+
<constraints nullable="false"/>
18+
</column>
19+
<column name="webhook_secret" type="VARCHAR(255)">
20+
<constraints nullable="false"/>
21+
</column>
22+
<column name="created_at" type="DATETIME">
23+
<constraints nullable="false"/>
24+
</column>
25+
<column name="updated_at" type="DATETIME"/>
26+
</createTable>
27+
</changeSet>
28+
29+
</databaseChangeLog>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
6+
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.30.xsd"
7+
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS">
8+
<changeSet id="1736959831825-1" author="gkhaavik">
9+
<addColumn tableName="orders">
10+
<column name="shipping_cost" type="DOUBLE"/>
11+
</addColumn>
12+
13+
<renameColumn tableName="orders" oldColumnName="total_amount" newColumnName="sub_total"
14+
columnDataType="DOUBLE"/>
15+
</changeSet>
16+
17+
</databaseChangeLog>
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<!DOCTYPE html>
2+
<html xmlns:th="http://www.thymeleaf.org" lang="en">
3+
<head>
4+
<title>New Order Received</title>
5+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6+
<style>
7+
.order-details {
8+
margin: 20px 0;
9+
}
10+
11+
.order-table {
12+
width: 100%;
13+
border-collapse: collapse;
14+
}
15+
16+
.order-table th, .order-table td {
17+
padding: 10px;
18+
border: 1px solid #ddd;
19+
}
20+
21+
.total {
22+
font-weight: bold;
23+
margin-top: 20px;
24+
}
25+
26+
.status {
27+
color: #2c5282;
28+
font-weight: bold;
29+
}
30+
31+
.customer-details {
32+
margin: 20px 0;
33+
padding: 15px;
34+
background-color: #f8f9fa;
35+
border-radius: 4px;
36+
}
37+
38+
.address-container {
39+
display: flex;
40+
justify-content: space-between;
41+
margin: 20px 0;
42+
}
43+
44+
.address-block {
45+
width: 48%;
46+
border: 1px solid #ddd;
47+
padding: 15px;
48+
border-radius: 4px;
49+
}
50+
51+
.address-block h3 {
52+
margin-top: 0;
53+
color: #2c5282;
54+
border-bottom: 1px solid #ddd;
55+
padding-bottom: 8px;
56+
margin-bottom: 12px;
57+
}
58+
59+
.address-line {
60+
margin: 5px 0;
61+
}
62+
63+
.action-button {
64+
display: inline-block;
65+
padding: 10px 20px;
66+
background-color: #2c5282;
67+
color: white;
68+
text-decoration: none;
69+
border-radius: 4px;
70+
margin-top: 20px;
71+
}
72+
</style>
73+
</head>
74+
<body>
75+
<h1>New Order Received - #<span th:text="${order.id}">123</span></h1>
76+
77+
<p>A new order has been received with the following details:</p>
78+
79+
<div class="customer-details">
80+
<h3>Customer Information</h3>
81+
<p>Name: <strong th:text="${order.customerName}">John Doe</strong></p>
82+
<p>Email: <strong th:text="${order.customerEmail}">john@example.com</strong></p>
83+
<p>Phone: <strong th:text="${order.customerPhone}">+1234567890</strong></p>
84+
</div>
85+
86+
<div class="order-details">
87+
<p>Order Status: <span class="status" th:text="${order.status}">PENDING</span></p>
88+
<p>Order Date: <span th:text="${#temporals.format(order.createdAt, 'dd-MM-yyyy HH:mm')}">01-01-2024</span></p>
89+
90+
<div class="address-container">
91+
<div class="address-block">
92+
<h3>Shipping Address</h3>
93+
<div class="address-line" th:text="${order.shippingAddress?.street}">123 Main St</div>
94+
<div class="address-line" th:text="${order.shippingAddress?.city}">City</div>
95+
<div class="address-line" th:if="${order.shippingAddress?.state}" th:text="${order.shippingAddress?.state}">
96+
State
97+
</div>
98+
<div class="address-line" th:text="${order.shippingAddress?.zipCode}">12345</div>
99+
<div class="address-line" th:text="${order.shippingAddress?.country}">Country</div>
100+
</div>
101+
102+
<div class="address-block" th:if="${order.billingAddress}">
103+
<h3>Billing Address</h3>
104+
<div class="address-line" th:text="${order.billingAddress?.street}">123 Main St</div>
105+
<div class="address-line" th:text="${order.billingAddress?.city}">City</div>
106+
<div class="address-line" th:if="${order.billingAddress?.state}" th:text="${order.billingAddress?.state}">
107+
State
108+
</div>
109+
<div class="address-line" th:text="${order.billingAddress?.zipCode}">12345</div>
110+
<div class="address-line" th:text="${order.billingAddress?.country}">Country</div>
111+
</div>
112+
</div>
113+
114+
<table class="order-table">
115+
<thead>
116+
<tr>
117+
<th>Product</th>
118+
<th>Quantity</th>
119+
<th>Price</th>
120+
<th>Total</th>
121+
</tr>
122+
</thead>
123+
<tbody>
124+
<tr th:each="item : ${order.items}">
125+
<td>
126+
<span th:text="${item.name}">Product Name</span>
127+
<div th:if="${item.variant}" th:text="${item.variant}">Variant Details</div>
128+
</td>
129+
<td th:text="${item.quantity}">1</td>
130+
<td th:text="${item.unitPrice}">$99.99</td>
131+
<td th:text="${item.totalPrice}">$99.99</td>
132+
</tr>
133+
</tbody>
134+
</table>
135+
136+
<p class="subtotal">Subtotal Amount: <span
137+
th:text="${order.subTotal}">$100.00</span></p>
138+
<p class="shippingCost">Shipping Cost: <span
139+
th:text="${order.shippingCost}">$8.00</span></p>
140+
<p class="total">Total Amount: <span
141+
th:text="${order.totalPrice}">$108.00</span></p>
142+
</div>
143+
144+
<a th:href="${dashboardUrl}" class="action-button">View Order in Dashboard</a>
145+
146+
<p>Please process this order as soon as possible.</p>
147+
</body>
148+
</html>

0 commit comments

Comments
 (0)