-
-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #51 from Reyzis2021/feature/Payment-(1-4)
- Loading branch information
Showing
21 changed files
with
404 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/main/java/com/zufar/onlinestore/OnlineStoreApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/main/java/com/zufar/onlinestore/payment/PaymentApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.zufar.onlinestore.payment; | ||
|
||
import com.stripe.exception.StripeException; | ||
import com.zufar.onlinestore.payment.dto.CreatePaymentDto; | ||
import com.zufar.onlinestore.payment.dto.PaymentDetailsDto; | ||
import com.zufar.onlinestore.payment.dto.PaymentDetailsWithTokenDto; | ||
import com.zufar.onlinestore.payment.exception.PaymentNotFoundException; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
public interface PaymentApi { | ||
|
||
ResponseEntity<PaymentDetailsWithTokenDto> paymentProcess(CreatePaymentDto paymentDto) throws StripeException; | ||
|
||
ResponseEntity<PaymentDetailsDto> getPaymentDetails(Long paymentId) throws PaymentNotFoundException; | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/zufar/onlinestore/payment/config/StripeConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.zufar.onlinestore.payment.config; | ||
|
||
import com.stripe.Stripe; | ||
import jakarta.annotation.PostConstruct; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
||
/** | ||
* This record responsible for displaying the Stripe Api configuration in Spring as a bean. | ||
* Configuration stores special keys with which Stripe controls data security. | ||
* | ||
* @param secretKey used to work with the Stripe Api from the backend side. | ||
* | ||
* @param publishableKey used to work with the Stripe Api from the frontend side. | ||
* | ||
* */ | ||
@ConfigurationProperties(prefix = "stripe") | ||
public record StripeConfiguration(String secretKey, String publishableKey) { | ||
|
||
@PostConstruct | ||
private void init() { | ||
Stripe.apiKey = secretKey; | ||
} | ||
|
||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/com/zufar/onlinestore/payment/controller/PaymentController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.zufar.onlinestore.payment.controller; | ||
|
||
import com.stripe.exception.StripeException; | ||
import com.zufar.onlinestore.payment.PaymentApi; | ||
import com.zufar.onlinestore.payment.dto.CreatePaymentDto; | ||
import com.zufar.onlinestore.payment.dto.PaymentDetailsDto; | ||
import com.zufar.onlinestore.payment.dto.PaymentDetailsWithTokenDto; | ||
import com.zufar.onlinestore.payment.dto.PriceDetailsDto; | ||
import com.zufar.onlinestore.payment.service.PaymentService; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@Slf4j | ||
@Validated | ||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping(PaymentController.PAYMENT_URL) | ||
public class PaymentController implements PaymentApi { | ||
|
||
public static final String PAYMENT_URL = "/api/v1/payment"; | ||
|
||
private final PaymentService paymentService; | ||
|
||
@PostMapping | ||
public ResponseEntity<PaymentDetailsWithTokenDto> paymentProcess(@RequestBody @Valid CreatePaymentDto paymentRequest) throws StripeException { | ||
log.info("payment process: receive request to create payment: paymentRequest: {}.", paymentRequest); | ||
PriceDetailsDto priceDetails = paymentRequest.priceDetails(); | ||
PaymentDetailsWithTokenDto processedPayment = paymentService.createPayment(paymentRequest.paymentMethodId(), | ||
priceDetails.totalPrice(), priceDetails.currency()); | ||
log.info("payment process: payment successfully processed: processedPayment: {}.", processedPayment); | ||
|
||
return ResponseEntity.status(HttpStatus.CREATED).body(processedPayment); | ||
} | ||
|
||
@GetMapping("/{paymentId}") | ||
public ResponseEntity<PaymentDetailsDto> getPaymentDetails(@PathVariable Long paymentId) { | ||
log.info("get payment details: receive payment id: paymentId: {}.", paymentId); | ||
PaymentDetailsDto retrievedPayment = paymentService.getPayment(paymentId); | ||
if (retrievedPayment == null) { | ||
log.info("get payment details: not found payment details by id: paymentId: {}.", paymentId); | ||
return ResponseEntity.notFound().build(); | ||
} | ||
log.info("get payment details: payment successfully retrieved: retrievedPayment: {}.", retrievedPayment); | ||
|
||
return ResponseEntity.ok().body(retrievedPayment); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/zufar/onlinestore/payment/dto/CreatePaymentDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.zufar.onlinestore.payment.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
public record CreatePaymentDto( | ||
|
||
@NotBlank(message = "Payment method id is mandatory attribute") | ||
String paymentMethodId, | ||
|
||
@NotNull(message = "Price details is mandatory attribute") | ||
PriceDetailsDto priceDetails) {} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/zufar/onlinestore/payment/dto/PaymentDetailsDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.zufar.onlinestore.payment.dto; | ||
|
||
import lombok.Builder; | ||
import java.math.BigDecimal; | ||
|
||
@Builder | ||
public record PaymentDetailsDto(Long paymentId, | ||
BigDecimal totalPrice, | ||
String currency, | ||
String status, | ||
String description) {} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/zufar/onlinestore/payment/dto/PaymentDetailsWithTokenDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.zufar.onlinestore.payment.dto; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record PaymentDetailsWithTokenDto(String paymentToken, PaymentDetailsDto paymentDetailsDto) {} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/zufar/onlinestore/payment/dto/PaymentWithTokenDetailsDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.zufar.onlinestore.payment.dto; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record PaymentWithTokenDetailsDto(String paymentToken, PaymentDetailsDto paymentDetailsDto) {} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/zufar/onlinestore/payment/dto/PriceDetailsDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.zufar.onlinestore.payment.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Size; | ||
|
||
import java.math.BigDecimal; | ||
|
||
public record PriceDetailsDto( | ||
|
||
@NotNull(message = "Total price is mandatory attribute") | ||
BigDecimal totalPrice, | ||
|
||
@NotBlank(message = "Currency is mandatory attribute") | ||
@Size(min = 3, max = 3, message = "Currency value must be only 3 characters long") | ||
String currency) {} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/zufar/onlinestore/payment/enums/PaymentStatus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.zufar.onlinestore.payment.enums; | ||
|
||
public enum PaymentStatus { | ||
REQUIRES_PAYMENT_METHOD, | ||
REQUIRES_CONFIRMATION, | ||
REQUIRES_CAPTURE, | ||
REQUIRES_ACTION, | ||
PROCESSING, | ||
CANCELED, | ||
SUCCEEDED | ||
} | ||
|
14 changes: 14 additions & 0 deletions
14
src/main/java/com/zufar/onlinestore/payment/exception/PaymentNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.zufar.onlinestore.payment.exception; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class PaymentNotFoundException extends RuntimeException { | ||
|
||
private final Long paymentId; | ||
|
||
public PaymentNotFoundException(Long paymentId) { | ||
super(String.format("Payment with id %s not found.", paymentId)); | ||
this.paymentId = paymentId; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/zufar/onlinestore/payment/mapper/PaymentConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.zufar.onlinestore.payment.mapper; | ||
|
||
import com.zufar.onlinestore.payment.dto.PaymentDetailsDto; | ||
import com.zufar.onlinestore.payment.model.Payment; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class PaymentConverter { | ||
|
||
public PaymentDetailsDto toDto(Payment entity) { | ||
return PaymentDetailsDto.builder() | ||
.paymentId(entity.getPaymentId()) | ||
.totalPrice(entity.getItemsTotalPrice()) | ||
.currency(entity.getCurrency()) | ||
.description(entity.getDescription()) | ||
.status(entity.getStatus()) | ||
.build(); | ||
} | ||
|
||
public Payment toEntity(PaymentDetailsDto dto) { | ||
return Payment.builder() | ||
.paymentId(dto.paymentId()) | ||
.itemsTotalPrice(dto.totalPrice()) | ||
.currency(dto.currency()) | ||
.description(dto.description()) | ||
.status(dto.status()) | ||
.build(); | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/zufar/onlinestore/payment/model/Payment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.zufar.onlinestore.payment.model; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Column; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.Getter; | ||
import java.math.BigDecimal; | ||
|
||
@Getter | ||
@Setter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
@Entity | ||
public class Payment { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "payment_id") | ||
private Long paymentId; | ||
|
||
@Column(nullable = false, name = "currency") | ||
private String currency; | ||
|
||
@Column(nullable = false, name = "items_total_price") | ||
private BigDecimal itemsTotalPrice; | ||
|
||
@Column(name = "status") | ||
private String status; | ||
|
||
@Column(name = "description") | ||
private String description; | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
src/main/java/com/zufar/onlinestore/payment/processor/PaymentProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.zufar.onlinestore.payment.processor; | ||
|
||
import com.stripe.Stripe; | ||
import com.stripe.exception.StripeException; | ||
import com.stripe.model.PaymentIntent; | ||
import com.stripe.model.PaymentMethod; | ||
import com.stripe.param.PaymentIntentCreateParams; | ||
import com.zufar.onlinestore.payment.config.StripeConfiguration; | ||
import com.zufar.onlinestore.payment.model.Payment; | ||
import jakarta.annotation.PostConstruct; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
import org.springframework.stereotype.Component; | ||
import java.math.BigDecimal; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Component | ||
public class PaymentProcessor { | ||
|
||
public static final String PAYMENT_MESSAGE = "Payment made by user: %s, using the payment method: %s."; | ||
public static final Integer PAYMENT_DELIMITER = 100; | ||
|
||
private final StripeConfiguration stripeConfig; | ||
|
||
public Pair<String, Payment> process(String paymentMethodId, BigDecimal totalPrice, String currency) throws StripeException { | ||
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodId); | ||
PaymentIntentCreateParams params = getPaymentParams(paymentMethod, totalPrice, currency); | ||
log.info("process: get payment intent params for payment creation: params: {}.", params); | ||
PaymentIntent paymentIntent = PaymentIntent.create(params); | ||
log.info("process: payment intent successfully created: paymentIntentId: {}.", paymentIntent.getId()); | ||
String paymentToken = paymentIntent.getClientSecret(); | ||
Payment payment = getProcessedPayment(paymentIntent); | ||
|
||
return Pair.of(paymentToken, payment); | ||
} | ||
|
||
private PaymentIntentCreateParams getPaymentParams(PaymentMethod paymentMethod, BigDecimal totalPrice, String currency) { | ||
String email = paymentMethod.getBillingDetails().getEmail(); | ||
return PaymentIntentCreateParams.builder() | ||
.setAmount(totalPrice.longValue() * PAYMENT_DELIMITER) | ||
.setCurrency(currency) | ||
.setPaymentMethod(paymentMethod.getId()) | ||
.setReceiptEmail(email) | ||
.setDescription(PAYMENT_MESSAGE.formatted(email, paymentMethod.getType())) | ||
.build(); | ||
} | ||
|
||
private Payment getProcessedPayment(PaymentIntent paymentIntent) { | ||
return Payment.builder() | ||
.itemsTotalPrice(BigDecimal.valueOf(paymentIntent.getAmount() / PAYMENT_DELIMITER)) | ||
.currency(paymentIntent.getCurrency()) | ||
.description(paymentIntent.getDescription()) | ||
.status(paymentIntent.getStatus()) | ||
.build(); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/zufar/onlinestore/payment/repository/PaymentRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.zufar.onlinestore.payment.repository; | ||
|
||
import com.zufar.onlinestore.payment.model.Payment; | ||
import org.springframework.data.repository.CrudRepository; | ||
|
||
public interface PaymentRepository extends CrudRepository<Payment, Long> { | ||
} |
Oops, something went wrong.