Comments (7)
Hey @Jabirr,
It seems like you'd have to bind the contract Laravel\Cashier\Plan\Contracts\PlanRepository
to your own implementation that implements this contract.
You can do this in a service provider of your own like this:
class AppServiceProvider extends ServiceProvider
{
/**
* Register the application services.
*/
public function register()
{
$this->app->bind(PlanRepository::class, DatabasePlanRepository::class);
}
}
Your DatabasePlanRepository class would then contain the logic of fetching the items from the database, but you'll have to make sure you're returning objects that implement Laravel\Cashier\Plan\Contracts\Plan
.
You can make your own eloquent Plan model, have it implement Laravel\Cashier\Plan\Contracts\Plan
, implement all the required methods, and then a database repository would be something like this:
use App\Plan;
use Laravel\Cashier\Plan\Contracts\PlanRepository;
class DatabasePlanRepository implements PlanRepository
{
/**
* @param string $name
* @return null|\Laravel\Cashier\Plan\Contracts\Plan
*/
public static function find(string $name)
{
return Plan::where('name', $name)->first();
}
/**
* @param string $name
* @return \Laravel\Cashier\Plan\Contracts\Plan
*/
public static function findOrFail(string $name)
{
return Plan::where('name', $name)->firstOrFail();
}
}
from cashier-mollie.
Hey @RobertBoes thx for the headstart.
Im trying to figure out what i need to put in a migration to migrate the right data.
I thought of something like this.
Do i need to add something in the cashier_plans.php so it can refer to a db too? because when you search for a plan that doesnt exist it will say that the plan doesnt exist. Using your code and then searching for a plan that doesnt exist just gives me a 404 page.
If i do search a plan that exist in my db it will show me this.
Idk if im just stupid (which probably is) but i dont really seem to understand what i need to do. If you could help me further that would be great.
-Jabir
from cashier-mollie.
I think you're on the right track. If you're using your own implementation of PlanRepository you don't need to worry about the config in cashier_plans
(because this isn't used anymore).
The 404 is because, in my example, DatabasePlanRepository->findOrFail()
uses the default eloquent method (findOrFail), this throws a ModelNotFound exception. I think you'll need to throw a PlanNotFoundException
. By looking at the ConfigPlanRepository, you can just do something like this:
public static function findOrFail(string $name)
{
if (($result = Plan::where('name', $name)->first()) != null) {
return $result;
} else {
throw new PlanNotFoundException;
}
}
One thing you're missing, is implementing the Plan contract (Laravel\Cashier\Plan\Contracts\Plan
) in your own model:
class Plan extends Model implements Laravel\Cashier\Plan\Contracts\Plan
{
}
If you're using an IDE you should then see you need to implement those methods. You can look how these methods are implemented in Plan. After you've implemented these methods it should work the same the config, but then with your own repository (the DB).
from cashier-mollie.
Hi @RobertBoes
First of all, thx for the quick reply. I kind of figured the implementing out too. I think the only issue is now is that it cant find a currency
How ever, searching through the code i found out it finds a plans value like this.
If I dd my own plan it will return this.
If i dd the plan using the normal plan configuration it will return this.
So i guess the next step would be returning the same values as using the normal configuration.
Do you have any idea how i could achieve this?
Thx a lot for helping out too btw!
- Jabir
from cashier-mollie.
Hey guys,
I figured it out with help of @RobertBoes ofcourse.
First of all to start using an custom PlanRepository. You have to bind the contract Laravel\Cashier\Plan\Contracts\PlanRepository to your own implementation that implements this contract.
You can do this in a service provider of your own like this:
class AppServiceProvider extends ServiceProvider
{
/**
* Register the application services.
*/
public function register()
{
$this->app->bind(PlanRepository::class, DatabasePlanRepository::class);
}
}
Your DatabasePlanRepository class would then contain the logic of fetching the items from the database, but you'll have to make sure you're returning objects that implement Laravel\Cashier\Plan\Contracts\Plan.
You can make your own eloquent Plan model, have it implement Laravel\Cashier\Plan\Contracts\Plan, implement all the required methods, and then a database repository would be something like this:
use App\Plan;
use Laravel\Cashier\Plan\Contracts\PlanRepository;
class DatabasePlanRepository implements PlanRepository
{
/**
* @param string $name
* @return null|\Laravel\Cashier\Plan\Contracts\Plan
*/
public static function find(string $name)
{
return Plan::where('name', $name)->first();
}
/**
* @param string $name
* @return \Laravel\Cashier\Plan\Contracts\Plan
*/
public static function findOrFail(string $name)
{
if (($result = Plan::where('name', $name)->first()) != null) {
return $result;
} else {
throw new PlanNotFoundException;
}
}
}
Now make a model for example Plan.php, I will show mine model. You have to import all the Plan functions into the model and change it with the values you save in your db.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Cashier\Order\OrderItemPreprocessorCollection;
use Money\Currency;
use Money\Money;
use Laravel\Cashier\Plan\Contracts\Plan as PlanImplements;
class Plan extends Model implements PlanImplements
{
protected $fillable = [
'name', 'amount', 'interval', 'description', 'currency','firstPaymentDescription','firstPaymentAmount'
];
public function getCurrency()
{
return $this->attributes['currency'];
}
public function getCode()
{
return $this->attributes['currency'];
}
public function amount()
{
$currency = new Currency($this->getCode());
return new Money($this->attributes['amount'] * 100, $currency);
}
/**
* @param \Money\Money $amount
* @return \Laravel\Cashier\Plan\Contracts\Plan
*/
public function setAmount(Money $amount)
{
}
/**
* @return string
*/
public function description()
{
return $this->attributes['description'];
}
/**
* @return string
*/
public function interval()
{
return $this->attributes['interval'];
}
/**
* @return string
*/
public function name()
{
return $this->attributes['name'];
}
/**
* The amount the customer is charged for a mandate payment.
*
* @return \Money\Money
*/
public function firstPaymentAmount()
{
$currency = new Currency($this->getCode());
return new Money($this->attributes['firstPaymentAmount'] * 100, $currency);
}
/**
* @param \Money\Money $firstPaymentAmount
* @return Plan
*/
public function setFirstPaymentAmount(Money $firstPaymentAmount)
{
}
/**
* @return string
*/
public function firstPaymentMethod()
{
}
/**
* @param string $firstPaymentMethod
* @return Plan
*/
public function setFirstPaymentMethod(?string $firstPaymentMethod)
{
}
/**
* The description for the mandate payment order item.
*
* @return string
*/
public function firstPaymentDescription()
{
return $this->attributes['firstPaymentDescription'];
}
/**
* @param string $firstPaymentDescription
* @return Plan
*/
public function setFirstPaymentDescription(string $firstPaymentDescription)
{
}
/**
* @return string
*/
public function firstPaymentRedirectUrl()
{
return "http://localhost:8000/redirect";
}
/**
* @param string $redirectUrl
* @return Plan
*/
public function setFirstPaymentRedirectUrl(string $redirectUrl)
{
}
/**
* @return string
*/
public function firstPaymentWebhookUrl()
{
return "webhookurl";
}
/**
* @param string $webhookUrl
* @return Plan
*/
public function setFirstPaymentWebhookUrl(string $webhookUrl)
{
}
/**
* @return \Laravel\Cashier\Order\OrderItemPreprocessorCollection
*/
public function orderItemPreprocessors()
{
}
/**
* @param \Laravel\Cashier\Order\OrderItemPreprocessorCollection $preprocessors
* @return \Laravel\Cashier\Plan\Contracts\Plan
*/
public function setOrderItemPreprocessors(OrderItemPreprocessorCollection $preprocessors)
{
$this->orderItemPreprocessors = $preprocessors;
return $this;
}
}
Now you can insert your plans into a db.
This was a quick fix but I am 100% sure that this can be made better.
I also want to thanks @RobertBoes for his time and help.
If someone has a beter way of achieving this. Id like to know that too!
from cashier-mollie.
@Jabirr could you also post your migration file? :)
from cashier-mollie.
@alexander-rieder ofc,
public function up()
{
Schema::create('plans', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('description')->nullable();
$table->string('interval')->default('monthly');
$table->double('amount');
$table->string('currency')->default('EUR');
$table->text('firstPaymentDescription')->nullable();
$table->double('firstPaymentAmount')->default(0.01);
$table->string('firstPaymentCurrency')->default('EUR');
$table->text('modules');
$table->softDeletes();
$table->timestamps();
});
}
The modules field is something i used my self to assign certain modules to plans.
from cashier-mollie.
Related Issues (20)
- Same plan with different intervals HOT 1
- Questions HOT 3
- First 1500 customer one year €25 discount / Exclude customers from discount when they have already have one HOT 3
- Guzzle timeout when trying to create a new customer. HOT 5
- PHP8 update confilct HOT 1
- Recurrent payment HOT 17
- Testing webhooks locally HOT 3
- Question about events HOT 6
- Get checkout URL for failed order payments HOT 1
- user id rounded up HOT 1
- Question regarding API KEY HOT 1
- Not Understanding HOT 1
- See when a subscription is up for renewal HOT 1
- Event OrderInvoiceAvailable is dispatched multiple times HOT 1
- 1305 SAVEPOINT trans2 does not exist HOT 1
- Charge based on days of the month left HOT 1
- How to create different pricings for subscriptions based on user country? HOT 2
- Current subscription end date HOT 5
- Is it possible to mandate multiple subscriptions in one initial payment HOT 3
- Interval of subscription not updating
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cashier-mollie.