mahdi khanzadi
5 سال پیش توسط mahdi khanzadi مطرح شد
32 پاسخ

معرفی پکیج لاراول با قابلیت ایجاد و یا تغییر درایور

سلام میخوام یه پکیج بهترون معرفی کنم که برای پرداخت آنلاین توسط درگاه های مختلف در لاراول ایجاد شده. شما با استفاده از این پکیج میتونید به درگاه های مختلف دسترسی داشته باشید بدون اینکه بخواید بعدا با تغییر درگاه باز کدتون رو تغییر بدید! تنها کاری که برای تغییر درگاه میکنید اینه که داخل تنظیمات اسم اون درگاه رو به صورت دیفالت قرار میدین.
لینک گیت هاب پکیج به صورت زیر هست

https://github.com/shetabit/payment

همچنین لینک پکیجیست به صورت زیره

https://packagist.org/packages/shetabit/payment

این پکیج نمره A و گرید ۱۰ گرفته . خوشحال میشم ازش استفاده کنید و همچنین معرفی کنیدش و درایورهاشو برای بانک های مختلف توسعه بدید تا یه پکیج یکپارچه برای بانک های ایران به وجود بیاد همچنین قانون SOLID با استفاده از این پکیج حفظ میشه یعنی اینکه بعدا اگه بانک رو خواستید عوض کنید دیگه کدهای قبلی رو که نوشته شده دست نمیزنید و فقط درایور بانک جدید رو قرار میدین. (مثل سیستم فایل لاراول یا سیستم کش لاراول که به صورت درایوری کار میکنه)

اگه از این پکیج استفاده کردین و خوشتون اومد بهش استار بدین. :)

این پکیج با درگاه های پرداخت مختلفی کار میکنه. در صورتی که درگاه مورد نظرتون رو در لیست درایورهای موجود پیدا نکردید میتونید برای درگاهی که استفاده میکنید درایور مورد نظرتون رو بسازید.

در صورتی که درایور مورد نظرتون موجود نیست, میتونید برای درگاه پرداخت موردنظرتون درایور بسازید.

نصب

نصب با استفاده از کامپوزر

$ composer require shetabit/payment

تنظیمات

درصورتی که از Laravel ۵.۵ یا ورژن های بالاتر استفاده میکنید نیازی به انجام تنظیمات providers و alias نخواهید داشت.

درون فایل config/app.php دستورات زیر را وارد کنید

# In your providers array.
'providers' => [
    ...
    ShetabitPaymentProviderPaymentServiceProvider::class,
],

# In your aliases array.
'aliases' => [
    ...
    'Payment' => ShetabitPaymentFacadePayment::class,
],

سپس دستور php artisan vendor:publish را اجرا کنید تا فایل config/payment.php درون دایرکتوری تنظیمات لاراول قرار بگیرد.

درون فایل تنظیمات در قسمت default driver میتوانید درایوری که قصد استفاده از ان را دارید قرار دهید تا تمامی پرداخت ها از آن طریق انجام شود.

// Eg. if you want to use zarinpal.
'default' => 'zarinpal',

سپس تنظیمات مرتبط با درایوری که قصد استفاده از ان را دارید انجام دهید

'drivers' => [
    'zarinpal' => [
        // Fill all the credentials here.
        'apiPurchaseUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json',
        'apiPaymentUrl' => 'https://www.zarinpal.com/pg/StartPay/',
        'apiVerificationUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json',
        'merchantId' => '',
        'callbackUrl' => 'http://yoursite.com/path/to',
        'description' => 'payment in '.config('app.name'),
    ],
    ...
]

طریقه استفاده

در تمامی پرداخت ها اطلاعات پرداخت درون صورتحساب شما نگهداری میشود. برای استفاده از پکیج ابتدا نحوه ی استفاده از کلاس Invoice به منظور کار با صورتحساب ها را توضیح میدهیم.

کار با صورتحساب ها

قبل از انجام هرکاری نیاز به ایجاد یک صورتحساب دارید. برای ایجاد صورتحساب میتوانید از کلاس Invoice استفاده کنید.

درون کد خودتون به شکل زیر عمل کنید:

# On the top of the file.
use ShetabitPaymentInvoice;
...

# create new invoice
$invoice = new Invoice;

# set invoice amount
$invoice->amount(۱۰۰۰);

# add invoice details : we have ۴ syntax
// ۱
$invoice->detail(['detailName' => 'your detail goes here']);
// ۲ 
$invoice->detail('detailName','your detail goes here');
// ۳
$invoice->detail(['name۱' => 'detail۱','name۲' => 'detail۲']);
// ۴
$invoice->detail('detailName۱','your detail۱ goes here')
        ->detail('detailName۲','your detail۲ goes here');

متدهای موجود برای کار با صورتحساب ها:

  • uuid : یک ایدی یونیک برای صورتحساب تنظیم میکند
  • getUuid : ایدی یونیک صورتحساب را برمیگرداند
  • detail : توضیحات یا مواردی که مرتبط به صورتحساب است را به صورتحساب اظافه میکند
  • getDetails : تمامی موارد مرتبطی که به صورتحساب افزوده شده است را برمیگرداند
  • amount : مقدار هزینه ای که باید پرداخت شود را مشخص میکند
  • getAmount : هزینه ی صورتحساب را برمیگرداند
  • transactionId : شماره تراکنش صورتحساب را مشخص میکند
  • getTransactionId : شماره تراکنش صورتحساب را برمیگرداند
  • via : درایوری که قصد پرداخت صورتحساب با آن را داریم مشخص میکند
  • getDriver : درایور انتخاب شده را برمیگرداند

ثبت درخواست برای پرداخت صورتحساب

به منظور پرداخت تمامی صورتحساب ها به یک شماره تراکنش بانکی یا transactionId نیاز خواهیم داشت.
با ثبت درخواست به منظور پرداخت میتوان شماره تراکنش بانکی را دریافت کرد:

# On the top of the file.
use ShetabitPaymentInvoice;
use ShetabitPaymentFacadePayment;
...

# create new invoice
$invoice = (new Invoice)->amount(۱۰۰۰);

# purchase the given invoice
Payment::purchase($invoice,function($driver, $transactionId) {
    // we can store $transactionId in database
});

# purchase method accepts a callback function
Payment::purchase($invoice, function($driver, $transactionId) {
    // we can store $transactionId in database
});

پرداخت صورتحساب

با استفاده از شماره تراکنش یا transactionId میتوانیم کاربر را به صفحه ی پرداخت بانک هدایت کنیم:

# On the top of the file.
use ShetabitPaymentInvoice;
use ShetabitPaymentFacadePayment;
...

# create new invoice
$invoice = (new Invoice)->amount(۱۰۰۰);
# purchase and pay the given invoice
// you should use return statement to redirect user to the bank's page.
return Payment::purchase($invoice, function($driver, $transactionId) {
    // store transactionId in database, we need it to verify payment in future.
})->pay();

# do all things together a single line
return Payment::purchase(
    (new Invoice)->amount(۱۰۰۰), 
    function($driver, $transactionId) {
        // store transactionId in database.
        // we need the transactionId to verify payment in future
    }
)->pay();

اعتبار سنجی پرداخت

بعد از پرداخت شدن صورتحساب توسط کاربر, بانک کاربر را به یکی از صفحات سایت ما برمیگردونه و ما با اعتبار سنجی میتونیم متوجه بشیم کاربر پرداخت رو انجام داده یا نه!

# On the top of the file.
use ShetabitPaymentFacadePayment;
use ShetabitPaymentExceptionsInvalidPaymentException;
...

# you need to verify the payment to insure the invoice has been paid successfully
// we use transaction's id to verify payments
// its a good practice to add invoice's amount.
try {
    Payment::amount(۱۰۰۰)->transactionId($transaction_id)->verify();
    ...
} catch (InvalidPaymentException $exception) {
    /**
        when payment is not verified , it throw an exception.
        we can catch the excetion to handle invalid payments.
        getMessage method, returns a suitable message that can be used in user interface.
    **/
    echo $exception->getMessage();
}

در صورتی که پرداخت توسط کاربر به درستی انجام نشده باشه یک استثنا از نوع InvalidPaymentException ایجاد میشود که حاوی پیام متناسب با پرداخت انجام شده است.

ایجاد درایور دلخواه:

برای ایجاد درایور جدید ابتدا نام (اسم) درایوری که قراره بسازید رو به لیست درایور ها اظافه کنید و لیست تنظیات مورد نیاز را نیز مشخص کنید.

'drivers' => [
    'zarinpal' => [...],
    'my_driver' => [
        ... # Your Config Params here.
    ]
]

کلاس درایوری که قصد ساختنش رو دارید باید کلاس ShetabitPaymentAbstractsDriver رو به ارث ببره.

به عنوان مثال:

namespace AppPackagesPaymentDriver;

use ShetabitPaymentInvoice;
use ShetabitPaymentAbstractsDriver;
use ShetabitPaymentExceptionsInvalidPaymentException;

class MyDriver extends Driver
{
    protected $invoice; // invoice

    protected $settings; // driver settings

    public function __construct(Invoice $invoice, $settings)
    {
        $this->invoice($invoice); // set the invoice
        $this->settings = (object) $settings; // set settings
    }

    // purchase the invoice, save its transactionId and finaly return it
    public function purchase() {
        // request for a payment transaction id
        ...

        $this->invoice->transactionId($transId);

        return $transId;
    }

    // redirect into bank using transactionId, to complete the payment
    public function pay() {
        // its better to set bankApiUrl in config/payment.php and retrieve it here:
        $bankUrl = $this->settings->bankApiUrl; // bankApiUrl is the config name.

        //prepare payment url
        $payUrl = $bankUrl.$this->invoice->getTransactionId();

        // redirect to the bank
        return redirect()->to($payUrl);
    }

    // verify the payment (we must verify to insure that user has paid the invoice)
    public function verify() {
        $verifyPayment = $this->settings->verifyApiUrl;

        $verifyUrl = $verifyPayment.$this->invoice->getTransactionId();

        ...

        /**
            then we send a request to $verifyUrl and if payment is not
            we throw an InvalidPaymentException with a suitable
        **/
        throw new InvalidPaymentException('a suitable message');
    }
}

بعد از اینکه کلاس درایور خودتون رو ایجاد کردید به فایل Config/payment.php برید و درایور خودتون رو در قسمت map اظافه کنید.

'map' => [
    ...
    'my_driver' => AppPackagesPaymentDriverMyDriver::class,
]

نکته: دقت کنید کلیدی که قسمت map قرار میدهید باید همنام با نامی باشد که در قسمت drivers قرار داده اید.

متدهای سودمند

  • callbackUrl : با استفاده از این متد به صورت داینامیک میتوانید ادرس صفحه ای که بعد از پرداخت انلاین کاربر به ان هدایت میشود را مشخص کنید
  # On the top of the file.
  use ShetabitPaymentInvoice;
  use ShetabitPaymentFacadePayment;
  ...

  # create new invoice
  $invoice = (new Invoice)->amount(۱۰۰۰);

  # purchase the given invoice
  Payment::callbackUrl($url)->purchase(
      $invoice, 
      function($driver, $transactionId) {
      // we can store $transactionId in database
    }
  );
  • amount: به کمک این متد میتوانید به صورت مستقیم هزینه صورتحساب را مشخص کنید
  # On the top of the file.
  use ShetabitPaymentInvoice;
  use ShetabitPaymentFacadePayment;
  ...

  # purchase (we set invoice to null)
  Payment::callbackUrl($url)->amount(۱۰۰۰)->purchase(
      null, 
      function($driver, $transactionId) {
      // we can store $transactionId in database
    }
  );
  • via : به منظور تغییر درایور در هنگام اجرای برنامه مورد استفاده قرار میگیرد
  # On the top of the file.
  use ShetabitPaymentInvoice;
  use ShetabitPaymentFacadePayment;
  ...

  # create new invoice
  $invoice = (new Invoice)->amount(۱۰۰۰);

  # purchase the given invoice
  Payment::via('driverName')->purchase(
      $invoice, 
      function($driver, $transactionId) {
      // we can store $transactionId in database
    }
  );

ثبت پرسش جدید
mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش آپدیت شد
0

@mehdisut

نمونه کد توی لینک زیر موجود هست

https://github.com/shetabit/payment/issues/46#issuecomment-599255439

بعد از اینکه کد ها رو از حالت فشرده خارج کردین دستور composer update بزنید تا اماده ی استفاده بشه.

در صورتی که نیاز به کمک دارید توی رپازیتوری پکیج issue ایجاد کنید.

https://github.com/shetabit/payment


حمید قربانی
@h.qorbani7 5 سال پیش آپدیت شد
0

قصد دارم پاسخی که داده بودم رو حذف کنم


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 5 سال پیش مطرح شد
0

با سلام. چنانچه مشکل یا سوالی وجود داره در رپازیتوری گیت هاب پکیج issue بزنید تا بررسی و رفع بشه.


Ahmad Kalantari
تخصص : Reactjs laravel dev
@amdk.1987 5 سال پیش مطرح شد
0

سلام
خیلی پکیج خوبی هست. ممنونم از زحماتتون.
فقط من نمیدونم شماره پیگیری بانک رو چجوری دریافت کنم. یعنی پرداخت انجام میشه چجوری باید verify کرد و صفحه برگشت رو طوری تنظیم کنم که نتیجه تراکنش و شماره پیگیری بانک رو ذخیره کنم؟


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 5 سال پیش مطرح شد
0

سلام به صورت زیر عمل کنید:

# On the top of the file.
use ShetabitPaymentFacadePayment;
use ShetabitPaymentExceptionsInvalidPaymentException;
...

# you need to verify the payment to insure the invoice has been paid successfully
// we use transaction's id to verify payments
// its a good practice to add invoice's amount.
try {
    Payment::amount(1000)->transactionId($transaction_id)->verify();
    ...
} catch (InvalidPaymentException $exception) {
    /**
        when payment is not verified , it throw an exception.
        we can catch the excetion to handle invalid payments.
        getMessage method, returns a suitable message that can be used in user interface.
    **/
    echo $exception->getMessage();
}

javid yarmohammadi
@javid.yarmohammadi 4 سال پیش مطرح شد
0

من این ارور رو دارم میشه راهنمایی کنید
"Call to undefined method Faker\Provider\Payment::purchase()"
ممنون
@khanzadimahdi


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش مطرح شد
0

@javid.yarmohammadi

سلام. پکیج رو نصب کردین؟ و اینکه طبق دستورالعمل مراحل رو انجام دادین؟ لینک زیر رو نگاه کنید.

https://github.com/shetabit/payment/blob/master/README-FA.md

تمام دستورات به صورت فارسی توضیح داده شده.


رامین رضائی
تخصص : گرافیست سابق و برنامه نویس حال
@raminr77 4 سال پیش مطرح شد
0

@khanzadimahdi
سلام
باتشکر از پکیج خوبی که نوشتی ! فوق العاده هست.

من برای پرداخت api خودم کد زیر رو نوشتم و پیام اطلاعات ارسال شده ناقص است را دریافت میکنم.
ممنون میشم اگر کمکم کنی که مشکلم حل بشه !

use Shetabit\Payment\Invoice;
function ZPay($amount){
    try {
        $invoice = (new Invoice)->amount($amount);
        return Payment::purchase($invoice, function($driver, $transactionId) {
            // store transactionId in database, we need it to verify payment in future.
        })->pay();
    } catch (Exception $e){
        return ResponseHelper(null , $e->getMessage() , false , 300);
    }
}

داخل پوشه config هم درایور ها و ... رو به صورت کامل تکمیل کردم ( برای زرین پال )

[
'default' => 'zarinpal',
'zarinpal' => [
            /* normal api */
            'apiPurchaseUrl' => 'https://ir.zarinpal.com/pg/services/WebGate/wsdl',
            'apiPaymentUrl' => 'https://www.zarinpal.com/pg/StartPay/',
            'apiVerificationUrl' => 'https://ir.zarinpal.com/pg/services/WebGate/wsdl',

            /* sandbox api */
            'sandboxApiPurchaseUrl' => 'https://sandbox.zarinpal.com/pg/services/WebGate/wsdl',
            'sandboxApiPaymentUrl' => 'https://sandbox.zarinpal.com/pg/StartPay/',
            'sandboxApiVerificationUrl' => 'https://sandbox.zarinpal.com/pg/services/WebGate/wsdl',

            /* zarinGate api */
            'zaringateApiPurchaseUrl' => 'https://ir.zarinpal.com/pg/services/WebGate/wsdl',
            'zaringateApiPaymentUrl' => 'https://www.zarinpal.com/pg/StartPay/:authority/ZarinGate',
            'zaringateApiVerificationUrl' => 'https://ir.zarinpal.com/pg/services/WebGate/wsdl',

            'mode' => env('PAYMENT_MODE', 'normal'), // can be normal, sandbox, zaringate
            'merchantId' => env('PAYMENT_KEY', ''),
            'callbackUrl' => env('PAYMENT_CALLBACK_URL', ''),
            'description' => 'تست درگاه بانکی',
        ]
]

mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش آپدیت شد
1

@raminr77

دوست عزیز خطای شما ناشی از عدم کامل بودن merchantId هست. درون تنظیمات این مقدار رو وارد کنید. یکبار خود تنظیمات رو بدون استفاده از env وارد کنید و تست کنید.

همچنین با استفاده از متد config میتونید تنظیمات رو به صورت داینامیک در هنگام اجرای برنامه اعمال کنید (مثلا از دیتابیس بخونید و اعمال کنید).

داکیومنت های پکیج رو از لینک زیر میتونید بخونید.

https://github.com/shetabit/payment/blob/master/README-FA.md


رامین رضائی
تخصص : گرافیست سابق و برنامه نویس حال
@raminr77 4 سال پیش مطرح شد
0

@khanzadimahdi
مرسی از کمکتون ! نباید از env استفاده میکردم.

ببخشید چطور میتونم لینک درگاه و درخواست رو از طریق api بفرستم برای کلاینت و بعد با کلیک کردن روی اون هدایتش کنم به زرین پال ؟

وقتی خود api پرداخت میخواد انجام بده سایت زرین پال رو کامل لود نمیکنه !

میخوام درخواست کاربر بیاد سمت api تائید بشه لینک درگاه براش ساخته بشه و توی اپ چایگزین بشه کاربر با کلیک روی اون بره درگاه و برگشت درگاه به api من باشه و دقیقا مثل اسنپ از سرور دوباره اپ رو باز کنم !


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش مطرح شد
0

@raminr77

لینک زیر دقیقا سوال شما رو مطرح کرده

https://github.com/shetabit/payment/issues/29


ملیکا شرفی
تخصص : برنامه نویس
@melikasharafi98 4 سال پیش مطرح شد
0

سلام ببخشید من اولین باره میخوام درگاه بزارم و اصلا اطلاعات خوبی ندارم و اینکه الان transactionId رو ما خودمون باید مقداردهی کنیم ؟؟


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش مطرح شد
0

@melikasharafi98

داکیومنت فارسی پکیج رو بخونید همه چیز رو نوشته راجبش

https://github.com/shetabit/payment/blob/master/README-FA.md


Ali Matin
تخصص : برنامه نویس
@ali.matin 4 سال پیش مطرح شد
0

منبع آموزشی تصویری هم در مورد این پکیج وجود داره؟


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش مطرح شد
-1

@ali.matin

اموزش تصویری وجود نداره. داکیومنت ها رو میتونید بخونید. هم فارسی هست و هم انگلیسی


ftp
تخصص : ساده
@ftp 4 سال پیش مطرح شد
0

@ali.matin
@melikasharafi98
@raminr77

اگه کسی با این پکیج تونسته کار کنه به من هم کمک کنه نمونه کد بده خیلی برام گنگه


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 4 سال پیش آپدیت شد
0

@mehdisut

نمونه کد توی لینک زیر موجود هست

https://github.com/shetabit/payment/issues/46#issuecomment-599255439

بعد از اینکه کد ها رو از حالت فشرده خارج کردین دستور composer update بزنید تا اماده ی استفاده بشه.

در صورتی که نیاز به کمک دارید توی رپازیتوری پکیج issue ایجاد کنید.

https://github.com/shetabit/payment


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 3 سال پیش مطرح شد
0

@ibmbarooei

ممنونم از شما. یه ویدیو در حد یک ربع درست کردم. یه مقدار نیاز به ویرایش داره. سر فرصت درستش کنم لینکشو توی داکیومنت های پکیج و همینجا نیز قرار میدم.

موفق باشید.


mb
تخصص : برنامه نویس لاراول
@ibmbarooei 3 سال پیش مطرح شد
0
کد خود را اینجpublic  function callback(Request $request ){

        try {
            $payment = Transaction::where('transaction_id', $transaction_id)->firstOrFail();
            Payment::amount(1000)->transactionId($transaction_id)->verify();

            $payment->update([
                'status' => 1
            ]);

            $payment->order()->update([
                'status' => 'completed'
            ]);

            alert()->success('پرداخت شما موفق بود');
            return "پرداخت شما موفق بود";

        } catch (InvalidPaymentException $exception) {
            /**
             * when payment is not verified, it will throw an exception.
             * We can catch the exception to handle invalid payments.
             * getMessage method, returns a suitable message that can be used in user interface.
             **/
            alert()->error($exception->getMessage());
            return redirect()->route('indexcart');
        }

    }

ا وارد کنید
*

من زمان برگشت مشکل دارم و مقادیرم اپدیت نمیشن و خطای 404 دارم اون transactio_idک تو اموزش گذاشتن چطوری معرفیش میککن
ابین خط
try {
Payment::amount(1000)->transactionId($transaction_id)->verify();
ممنون واقعا توضیح بدن @khanzadimahdi


mahdi khanzadi
تخصص : backend developer at Snapp mar...
@khanzadimahdi 3 سال پیش مطرح شد
0

transaction_id رو باید توی دیتابیس ذخیره کنید تا در مراحل بعدی بتونید ازش استفاده کنید.


mb
تخصص : برنامه نویس لاراول
@ibmbarooei 3 سال پیش مطرح شد
0

@khanzadimahdi واقعا ممنون اگر ویدیو رو بزارید🙏👏👏👏👏👏👏👏👏👏👏👏👏👏


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام