449 lines
11 KiB
PHP
449 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: loann
|
|
* Date: 23/04/19
|
|
* Time: 16:29
|
|
*/
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Entity\Offer;
|
|
use App\Entity\Subscription;
|
|
use App\Entity\User;
|
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
|
|
class StripeService
|
|
{
|
|
protected $api_key;
|
|
protected $doctrine;
|
|
|
|
public function __construct(
|
|
ContainerInterface $container,
|
|
\Doctrine\Common\Persistence\ManagerRegistry $doctrine
|
|
)
|
|
{
|
|
$this->api_key = $container->getParameter('stripe_secret');
|
|
$this->doctrine = $doctrine;
|
|
}
|
|
|
|
public function initKey()
|
|
{
|
|
\Stripe\Stripe::setApiKey($this->api_key);
|
|
}
|
|
|
|
// Check if the user is linked to a Stripe cutomer, otherwise create one, then get its id
|
|
public function retrieveCustomerId(User $user, $token)
|
|
{
|
|
if ($user->getStripeCustomerId()) {
|
|
|
|
$customer_id = $user->getStripeCustomerId();
|
|
|
|
} else {
|
|
|
|
$email = $user->getUsername();
|
|
$em = $this->doctrine->getManager();
|
|
|
|
$customer = \Stripe\Customer::create([
|
|
"email" => $email,
|
|
"source" => $token,
|
|
]);
|
|
|
|
$customer_id = $customer['id'];
|
|
|
|
$user->setStripeCustomerId($customer_id);
|
|
$em->persist($user);
|
|
$em->flush();
|
|
|
|
}
|
|
|
|
return $customer_id;
|
|
}
|
|
|
|
|
|
/* CHARGE -------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
public function pay(User $user, $cart, $token)
|
|
{
|
|
$this->initKey();
|
|
|
|
$customer_id = $this->retrieveCustomerId($user, $token);
|
|
|
|
$count = 0;
|
|
|
|
foreach ($cart as $product) {
|
|
|
|
if ($destination_account = $product->getUser()->getStripeAccount()) {
|
|
if ($this->createCharge($customer_id, $product, $destination_account)) {
|
|
$count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'message' => $count . " paid products",
|
|
];
|
|
}
|
|
|
|
// Create a charge
|
|
public function createCharge($customer_id, $product, $destination_account)
|
|
{
|
|
try {
|
|
|
|
\Stripe\Charge::create([
|
|
"amount" => $product->getPrice() / 100,
|
|
"currency" => "eur",
|
|
"customer" => $customer_id,
|
|
"description" => "Paiement pour le produit " . $product->getName(),
|
|
"metadata"=> "additionnal_informations",
|
|
"destination" => [
|
|
"account" => $destination_account,
|
|
],
|
|
]);
|
|
|
|
$success = true;
|
|
|
|
} catch (\Exception $e) {
|
|
$success = false;
|
|
}
|
|
|
|
return $success;
|
|
|
|
}
|
|
|
|
// Retrieve a charge
|
|
public function retrieveCharge($charge_id)
|
|
{
|
|
$this->initKey();
|
|
|
|
return \Stripe\Charge::retrieve($charge_id);
|
|
}
|
|
|
|
// Refund a charge
|
|
public function refundCharge($charge_id)
|
|
{
|
|
$this->initKey();
|
|
|
|
$success = false;
|
|
|
|
try {
|
|
|
|
\Stripe\Refund::create([
|
|
"charge" => $charge_id
|
|
]);
|
|
|
|
$success = true;
|
|
$message = "Refund done";
|
|
|
|
} catch(\Exception $e) {
|
|
$message = $e->getMessage();
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
}
|
|
|
|
|
|
/* SUBSCRIPTION --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
// Create a subscription
|
|
public function newSubscription(User $user, $plan_id, $token)
|
|
{
|
|
$this->initKey();
|
|
|
|
$customer_id = $this->retrieveCustomerId($user, $token);
|
|
$message = "Subscription created.";
|
|
$success = false;
|
|
$em = $this->doctrine->getManager();
|
|
|
|
// Checking that the user has not already subscribed to this plan
|
|
if ($this->userHasSubscribed($user, $plan_id)) {
|
|
|
|
$message = "Subscription already existing";
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
}
|
|
|
|
try {
|
|
|
|
$stripeSubscription = \Stripe\Subscription::create([
|
|
"customer" => $customer_id,
|
|
"items" => [
|
|
[
|
|
"plan" => $plan_id,
|
|
],
|
|
]
|
|
]);
|
|
|
|
$subscription = new Subscription();
|
|
$subscription->setCustomerId($customer_id);
|
|
$subscription->setPlanId($plan_id);
|
|
$subscription->setCreatedAt(new \DateTime());
|
|
$subscription->setStripeId($stripeSubscription['id']);
|
|
|
|
$em->persist($subscription);
|
|
$em->flush();
|
|
|
|
$success = true;
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
$message = $e->getMessage();
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
|
|
}
|
|
|
|
// Cancel a subscription
|
|
public function cancelSubscription(Subscription $subscription)
|
|
{
|
|
$this->initKey();
|
|
|
|
$subscription_id = $subscription->getStripeId();
|
|
$success = false;
|
|
$message = "Entity Subscription doesn t have an id";
|
|
|
|
if ($subscription_id) {
|
|
|
|
try {
|
|
|
|
$sub = \Stripe\Subscription::retrieve($subscription_id);
|
|
$sub->cancel();
|
|
|
|
$success = true;
|
|
$message = "Subscription cancelled";
|
|
|
|
} catch(\Exception $e) {
|
|
|
|
$message = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
}
|
|
|
|
// Check if the user has subscribed to the plan or not
|
|
public function userHasSubscribed(User $user, $plan_id)
|
|
{
|
|
$subscriptionRepository = $this->doctrine->getRepository('App:Subscription');
|
|
|
|
$customer_id = $user->getStripeCustomerId();
|
|
$subscribed = false;
|
|
|
|
if ($customer_id) {
|
|
$subscription = $subscriptionRepository->findBy([
|
|
'plan_id' => $plan_id,
|
|
'customer_id' => $customer_id,
|
|
'cancelled_at' => null
|
|
]);
|
|
|
|
if ($subscription)
|
|
$subscribed = true;
|
|
}
|
|
|
|
return $subscribed;
|
|
}
|
|
|
|
|
|
/* PAYOUT -------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
public function createPayout(User $user, $product)
|
|
{
|
|
$this->initStripe();
|
|
|
|
$success = false;
|
|
$message = "User doesnt have an stripe account id";
|
|
|
|
if ($account_id = $user->getStripeAccountId()) {
|
|
|
|
try {
|
|
\Stripe\Payout::create(
|
|
[
|
|
"amount" => $product->getPrice(),
|
|
"currency" => "eur",
|
|
],
|
|
[
|
|
"stripe_account" => $account_id
|
|
]
|
|
);
|
|
|
|
$success = true;
|
|
$message = "Payout created";
|
|
|
|
} catch(\Exception $e) {
|
|
$message = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
}
|
|
|
|
|
|
/* PRODUCT --------------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
// Create a product
|
|
public function createProduct($product)
|
|
{
|
|
$this->initStripe();
|
|
|
|
if ($product->getStripeId()) {
|
|
return $this->updateProduct($product);
|
|
}
|
|
|
|
$url = "url_product";
|
|
|
|
try {
|
|
$prod = \Stripe\Product::create([
|
|
"name" => $product->getTitle(),
|
|
"type" => "good",
|
|
"description" => $product->getDescription(),
|
|
"metadata" => [
|
|
"mail_vendeur" => $product->getUser() ? $product->getUser()->getUsername() : null,
|
|
"entreprise_vendeur" => $product->getUser() ? $product->getUser()->getCompany() : null,
|
|
"date_publication" => $product->getDatePublication()->format('d/m/Y'),
|
|
"date_max" => $product->getMaxSellDate()->format('d/m/Y'),
|
|
"adresse" => $product->getAddress() . ' ' . $product->getCp() . ' ' . $product->getVille(),
|
|
"prix HT" => $product->getPriceHT() .'€',
|
|
"prix TTC" => $product->getPriceTTC() . '€',
|
|
"quantité" => $product->getTotalQuantity(),
|
|
],
|
|
"url" => $url
|
|
]);
|
|
|
|
$product->setStripeId($prod->id);
|
|
|
|
return "success";
|
|
|
|
} catch (\Exception $e) {
|
|
return $e->getMessage();
|
|
}
|
|
|
|
}
|
|
|
|
// Update a product
|
|
public function updateProduct($product)
|
|
{
|
|
$this->initStripe();
|
|
|
|
$url = "url_product";
|
|
|
|
try {
|
|
\Stripe\Product::update(
|
|
$product->getStripeId(),
|
|
[
|
|
"name" => $product->getTitle(),
|
|
"description" => $product->getDescription(),
|
|
"metadata" => [
|
|
"date_max" => $product->getMaxSellDate()->format('d/m/Y'),
|
|
"adresse" => $product->getAddress() . ' ' . $product->getCp() . ' ' . $product->getVille(),
|
|
"prix HT" => $product->getPriceHT() .'€',
|
|
"prix TTC" => $product->getPriceTTC() . '€',
|
|
"quantité" => $product->getTotalQuantity(),
|
|
],
|
|
"url" => $url
|
|
]);
|
|
|
|
return "success";
|
|
} catch (\Exception $e) {
|
|
return $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// Delete a product
|
|
public function deleteProduct($product)
|
|
{
|
|
$this->initStripe();
|
|
|
|
try {
|
|
$product = \Stripe\Product::retrieve($product->getStripeId());
|
|
$product->delete();
|
|
|
|
$success = true;
|
|
$message = "Product deleted";
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
$success = false;
|
|
$message = $e->getMessage();
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
|
|
}
|
|
|
|
|
|
/* COUPON -------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
public function createCoupon($amount, $id, $duration, $type = '%')
|
|
{
|
|
$this->initStripe();
|
|
|
|
if ($type == "€")
|
|
$off = "amount_off";
|
|
else {
|
|
$off = "percent_off";
|
|
}
|
|
|
|
try {
|
|
|
|
\Stripe\Coupon::create([
|
|
$off => $amount,
|
|
"duration" => $duration,
|
|
// "duration_in_months" => 3,
|
|
"id" => $id
|
|
]);
|
|
|
|
$success = true;
|
|
$message = "Coupon created";
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
$success = false;
|
|
$message = $e->getMessage();
|
|
}
|
|
|
|
return [
|
|
'message' => $message,
|
|
'success' => $success
|
|
];
|
|
|
|
}
|
|
|
|
public function retrieveCoupon($coupon_token)
|
|
{
|
|
$this->initStripe();
|
|
|
|
$coupon = \Stripe\Coupon::retrieve($coupon_token);
|
|
|
|
return $coupon;
|
|
}
|
|
|
|
|
|
|
|
// TODO
|
|
// Invoice
|
|
// check when card is not valid anymore, warn the admins
|
|
} |