Skip to content
This repository was archived by the owner on Aug 21, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions kubernetes-dev/config/paypal-secret.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ type: Opaque
data:
paypal-client-id: SETUP_PAYPAL_CLIENT_ID_REPLACEME
paypal-client-secret: SETUP_PAYPAL_CLIENT_SECRET_REPLACEME
paypal-webhook-id: SETUP_PAYPAL_WEBHOOK_ID_REPLACEME
8 changes: 8 additions & 0 deletions kubernetes-dev/ingress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ spec:
port:
number: 80

- path: /paypal/webhooks
pathType: Prefix
backend:
service:
name: payment-paypal
port:
number: 80

- path: /accounting
pathType: Prefix
backend:
Expand Down
5 changes: 5 additions & 0 deletions kubernetes-dev/microservices/payment-paypal-microservice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ spec:
secretKeyRef:
name: paypal-secret
key: paypal-client-secret
- name: PAYPAL_WEBHOOK_ID
valueFrom:
secretKeyRef:
name: paypal-secret
key: paypal-webhook-id
- name: SENTRY_DSN
valueFrom:
secretKeyRef:
Expand Down
1 change: 1 addition & 0 deletions kubernetes/config/paypal-secret.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ type: Opaque
data:
paypal-client-id: SETUP_PAYPAL_CLIENT_ID_REPLACEME
paypal-client-secret: SETUP_PAYPAL_CLIENT_SECRET_REPLACEME
paypal-webhook-id: SETUP_PAYPAL_WEBHOOK_ID_REPLACEME
8 changes: 8 additions & 0 deletions kubernetes/ingress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ spec:
port:
number: 80

- path: /paypal/webhooks
pathType: Prefix
backend:
service:
name: payment-paypal
port:
number: 80

- path: /accounting
pathType: Prefix
backend:
Expand Down
5 changes: 5 additions & 0 deletions kubernetes/microservices/payment-paypal-microservice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ spec:
secretKeyRef:
name: paypal-secret
key: paypal-client-secret
- name: PAYPAL_WEBHOOK_ID
valueFrom:
secretKeyRef:
name: paypal-secret
key: paypal-webhook-id
- name: SENTRY_DSN
valueFrom:
secretKeyRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import com.funixproductions.core.tools.pdf.tools.VATInformation;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;
import org.springframework.lang.Nullable;

import java.io.Serializable;
Expand Down Expand Up @@ -108,5 +105,19 @@ public static class Price implements Serializable {
@Nullable
@Min(value = 0, message = "Le prix de la réduction doit être supérieur ou égal à 0")
private Double discount;

public Price(@NonNull Double ht, @Nullable Double tax) {
this.ht = ht;
this.tax = tax == null ? 0 : tax;
this.ttc = ht + (tax == null ? 0 : tax);
this.discount = null;
}

public Price(@NonNull Double ht) {
this.ht = ht;
this.tax = 0.0;
this.ttc = ht;
this.discount = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.funixproductions.api.payment.paypal.client.clients;

import com.funixproductions.api.payment.paypal.client.dtos.responses.PaypalPlanDTO;
import com.funixproductions.core.crud.dtos.PageDTO;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.*;

/**
* Client pour gérer les plans d'abonnements Paypal.
*/
public interface PaypalPlanClient {

/**
* Crée un abonnement mensuel sur Paypal.
* @param paypalPlanDTO Dto pour créer un abonnement mensuel sur Paypal
* @return le plan créé (201 Http)
*/
@PostMapping
PaypalPlanDTO create(@RequestBody @Valid PaypalPlanDTO paypalPlanDTO);

/**
* Récupère un plan par son id.
* @param id id du plan
* @return le plan (200 Http)
*/
@GetMapping("{id}")
PaypalPlanDTO getPlanById(@PathVariable @Valid @NotBlank String id);

@GetMapping
PageDTO<PaypalPlanDTO> getAll(
@RequestParam(value = "page",defaultValue = "0") String page,
@RequestParam(value = "elemsPerPage",defaultValue = "300") String elemsPerPage,
@RequestParam(value = "search",defaultValue = "") String search,
@RequestParam(value = "sort",defaultValue = "") String sort
);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.funixproductions.api.payment.paypal.client.clients;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(
name = "FunixProductionsPaypalPlanFeignClient",
url = "http://payment-paypal",
path = "/paypal/plans"
)
public interface PaypalPlanFeignClient extends PaypalPlanClient {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.funixproductions.api.payment.paypal.client.clients;

import com.funixproductions.api.payment.paypal.client.dtos.requests.paypal.PaypalCreateSubscriptionDTO;
import com.funixproductions.api.payment.paypal.client.dtos.responses.PaypalSubscriptionDTO;
import com.funixproductions.core.crud.dtos.PageDTO;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.*;

/**
* Client pour gérer les abonnements des utilisateurs sur Paypal.
*/
public interface PaypalSubscriptionClient {

@PostMapping
PaypalSubscriptionDTO subscribe(@RequestBody @Valid PaypalCreateSubscriptionDTO request);

@GetMapping("{id}")
PaypalSubscriptionDTO getSubscriptionById(@PathVariable @Valid @NotBlank String id);

@PostMapping("{id}/pause")
PaypalSubscriptionDTO pauseSubscription(@PathVariable @Valid @NotBlank String id);

@PostMapping("{id}/activate")
PaypalSubscriptionDTO activateSubscription(@PathVariable @Valid @NotBlank String id);

@PostMapping("{id}/cancel")
void cancelSubscription(@PathVariable @Valid @NotBlank String id);

@GetMapping
PageDTO<PaypalSubscriptionDTO> getAll(
@RequestParam(value = "page",defaultValue = "0") String page,
@RequestParam(value = "elemsPerPage",defaultValue = "300") String elemsPerPage,
@RequestParam(value = "search",defaultValue = "") String search,
@RequestParam(value = "sort",defaultValue = "") String sort
);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.funixproductions.api.payment.paypal.client.clients;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(
name = "FunixProductionsPaypalSubscriptionFeignClient",
url = "http://payment-paypal",
path = "/paypal/subscriptions"
)
public interface PaypalSubscriptionFeignClient extends PaypalSubscriptionClient {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.funixproductions.api.payment.paypal.client.dtos.requests.paypal;

import com.funixproductions.api.payment.paypal.client.dtos.responses.PaypalPlanDTO;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.UUID;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class PaypalCreateSubscriptionDTO {

@NotNull(message = "Le plan est obligatoire")
private PaypalPlanDTO plan;

@NotNull(message = "L'utilisateur id est obligatoire")
private UUID funixProdUserId;

@NotBlank(message = "L'URL d'annulation est obligatoire")
private String cancelUrl;

@NotBlank(message = "L'URL de retour valide est obligatoire")
private String returnUrl;

@NotBlank(message = "La marque est obligatoire")
private String brandName;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.funixproductions.api.payment.paypal.client.dtos.responses;

import com.funixproductions.core.crud.dtos.ApiDTO;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* Dto pour créer un abonnement mensuel sur Paypal.
* <a href="https://developer.paypal.com/docs/api/catalog-products/v1/#products_create">Create Product</a>
* <a href="https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create">Create plan</a>
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class PaypalPlanDTO extends ApiDTO {

/**
* The plan id de paypal
*/
private String planId;

/**
* The subscription name.
*/
@NotBlank(message = "Le nom du produit est obligatoire")
@Size(min = 1, max = 127, message = "Le nom du produit doit contenir entre 1 et 127 caractères")
private String name;

/**
* The subscription description
*/
@NotBlank(message = "La description du produit est obligatoire")
@Size(min = 1, max = 256, message = "La description du produit doit contenir entre 1 et 256 caractères")
private String description;

/**
* The image URL for the product.
*/
@NotBlank(message = "L'URL de l'image du produit est obligatoire")
@Size(min = 1, max = 2000, message = "L'URL de l'image du produit doit contenir entre 1 et 2000 caractères")
private String imageUrl;

/**
* The home page URL for the product.
*/
@NotBlank(message = "L'URL de la page d'accueil du produit est obligatoire")
@Size(min = 1, max = 2000, message = "L'URL de la page d'accueil du produit doit contenir entre 1 et 2000 caractères")
private String homeUrl;

/**
* The subscription price. HT Hors taxes
*/
@NotNull(message = "Le prix du produit est obligatoire")
@Min(value = 1, message = "Le prix du produit doit être supérieur à 1")
private Double price;

/**
* Le nom du projet auquel est associé le plan, exemple pacifista pour un pacifista+
*/
@NotNull(message = "Le nom du projet est obligatoire")
@Size(min = 1, max = 50, message = "Le nom du projet doit contenir entre 1 et 50 caractères")
private String projectName;

public PaypalPlanDTO(String name, String description, String imageUrl, String homeUrl, Double price, String projectName) {
this.name = name;
this.description = description;
this.imageUrl = imageUrl;
this.homeUrl = homeUrl;
this.price = price;
this.projectName = projectName;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof final PaypalPlanDTO other) {
return this.name.equals(other.name) &&
this.description.equals(other.description) &&
this.imageUrl.equals(other.imageUrl) &&
this.homeUrl.equals(other.homeUrl) &&
this.price.equals(other.price) &&
this.projectName.equals(other.projectName) &&
(this.planId != null && other.planId != null && this.planId.equals(other.planId)) &&
super.equals(obj);
} else {
return false;
}
}

@Override
public int hashCode() {
return this.name.hashCode() +
this.description.hashCode() +
this.imageUrl.hashCode() +
this.homeUrl.hashCode() +
this.price.hashCode() +
this.projectName.hashCode() +
(this.planId != null ? this.planId.hashCode() : 0) +
super.hashCode();
}
}
Loading