stripe-bundle/src/Service/StripeService.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
}