Laravel 이니시스 결제



It’s not intended to replace the whole manual from INICIS, one of major Korean PGs to allow you to accept Korean credit cards. The objective of this writing is provide you a feasible way to use INICIS while using Laravel 4.2.x PHP framework. It was a pain in the ass to read through their unbelievably crappy manual though. At the time of this writing, I am using L4 for my current project so bear with me until I upgrade to the version 5 if that’s what you want. So, let’s cut to the chase;

They have this legacy PHP class called INIpay50 which seems to be written in old school days. You may simply want to put them in the following directory;


and autoload ’em with composer.json like this;

    "autoload": {
        "classmap": [

Don’t forget to php artisan dump-audoload after updating composer.json. Another caveat you should keep in mind is that encryption key-file directory and log directory are under the directory as you may need to check out them later.

Unfortunately, the way the legacy classes are rigidly coupled with Views and JavaScripts forces me to follow their fragile coding style at least with my level of understanding of how they work. Too bad.

The following is the migration I work with. You should make a similar one for your own good:

    public function up()
        Schema::create('payments', function(Blueprint $table)

Then, the model, Payment:

    <?php namespace Teeshot\Payments;

    use Eloquent;
    use Laracasts\Presenter\PresentableTrait;

    class Payment extends Eloquent {

        use PresentableTrait;

        protected $fillable = [ 'user_id', 'transaction_id', 'payment_type', 'item_name', 'item_price', 'recurring', 'realname', 'phone', 'email', 'started_at', 'ended_at' ];

        protected $table = 'payments';
        protected $dates = [ 'started_at', 'ended_at' ];
        protected $presenter = 'Teeshot\Payments\PaymentPresenter';

        public function user()
            return $this->belongsTo('User');

Then the presenter which allows to separate logics from its View. You can ignore this but I’m attaching this for the integrity of source codes.

    <?php namespace Teeshot\Payments;

    use Carbon\Carbon;
    use Laracasts\Presenter\Presenter;

    class PaymentPresenter extends Presenter {

        public function typeOfPayment($key)

            $arrTypes = [
                'DirectBank'=>'실시간 계좌이체',

            return $arrTypes[$key];

        public function nameOfCard($key)
            $arrCards = [

            return $arrCards[$key];

        public function nameOfCardIssuer($key)
            $arrIssuers = [
                "88"=>"신한은행(조흥 통합)"

            return $arrIssuers[$key];

Then, the controller. I believe it wouldn’t be hard to follow the logic. The only thing I want to mention is how the validate method works in the paymentForm class. It’s a simple decorator after validating user inputs, which returns only the data that Payment model requires.


    use Teeshot\Forms\PaymentForm;
    use Teeshot\Payments\Payment;
    use Teeshot\Payments\PaymentRepository;
    use Teeshot\Events\UserHasPurchased;
    use Carbon\Carbon;

    class PaymentsController extends \BaseController
        private $paymentForm;
        protected $payments;
        protected $me;

        function __construct(PaymentForm $paymentForm, PaymentRepository $paymentRepository)

            $this->paymentForm = $paymentForm;
            $this->payments = $paymentRepository;
            $this->me = Auth::user();

        public function preview()
            $formData = $this->paymentForm->validate(Input::all());

            $keys = Config::get('services.inicis');
            $transition_id = 'TEESHOT-INICIS-'.date("ymd-His").'-'.sprintf("%09d", $this->me->id);  // INICIS-150325-142412-0000000031

            $inipay = new INIpay50;
            $inipay->SetField("inipayhome", app_path()."/classes/INIpay50");
            $inipay->SetField("type", "chkfake");
            $inipay->SetField("debug", "false"); // to exclude logging
            $inipay->SetField("enctype", "asym");
            $inipay->SetField("admin", $keys['admin']);
            $inipay->SetField("checkopt", "false");
            $inipay->SetField("mid", $keys['mid']);
            $inipay->SetField("price", $formData['amount']);
            $inipay->SetField("nointerest", "no");
            $inipay->SetField("quotabase", "선택:일시불:2개월:3개월:6개월");

            if ($inipay->GetResult("ResultCode") != "00")
                dd( '알수없는 에러 ('.$inipay->GetResult("ResultMsg").')' );

            Session::put('INI_MID', $keys['mid']);
            Session::put('INI_ADMIN', $keys['admin']);
            Session::put('INI_OID', $transition_id);
            Session::put('INI_PRICE', $formData['amount']);
            Session::put('INI_RN', $inipay->GetResult("rn"));
            Session::put('INI_ENCTYPE', $inipay->GetResult("enctype"));

            // Add 3 more data that this shit requires
            $formData['today'] = date("Ymd", time());
            $formData['ini_encfield'] = $inipay->GetResult("encfield");
            $formData['ini_certid'] = $inipay->GetResult("certid");

            return View::make('payments.preview')->with(compact('formData'));

        public function bill()
            $inipay = new INIpay50;
            $inipay->SetField("inipayhome", app_path()."/classes/INIpay50");
            $inipay->SetField("type", "securepay");
            $inipay->SetField("pgid", "INIphp".Input::get('pgid'));
            $inipay->SetField("admin", Session::get('INI_ADMIN'));
            $inipay->SetField("debug", "false");
            $inipay->SetField("uid", Input::get('uid'));
            $inipay->SetField("goodname", Input::get('goodname'));
            $inipay->SetField("currency", Input::get('currency'));
            $inipay->SetField("rn", Session::get('INI_RN'));
            $inipay->SetField("price", Session::get('INI_PRICE'));
            $inipay->SetField("enctype", Session::get('INI_ENCTYPE'));
            $inipay->SetField("buyername", Input::get('buyername'));
            $inipay->SetField("buyertel",  Input::get('buyertel'));
            $inipay->SetField("buyeremail", Input::get('buyeremail'));
            $inipay->SetField("paymethod", Input::get('paymethod'));
            $inipay->SetField("encrypted", Input::get('encrypted'));
            $inipay->SetField("sessionkey", Input::get('sessionkey'));
            $inipay->SetField("url", ""); // REPLACE IT WITH YOUR URL
            $inipay->SetField("cardcode", Input::get('cardcode'));
            $inipay->SetField("parentemail", "");
            $inipay->SetField("joincard", Input::get('joincard'));
            $inipay->SetField("joinexpire", Input::get('joinexpire'));
            $inipay->SetField("id_customer", Input::get('id_customer'));

            if ($inipay->GetResult("ResultCode") != "00")
                dd( '알수없는 에러 ('.$inipay->GetResult("ResultMsg").')' );
            else {

                $data = [
                    'transaction_id' => Input::get('oid'),
                    'payment_type' => Input::get('paymethod'),
                    'item_name' => Input::get('goodname'),
                    'item_price' => Input::get('price'),
                    'recurring' => Input::get('recurring'),
                    'realname' => $this->me->profile->realname,
                    'phone' => $this->me->profile->phone,
                    'email' => $this->me->email,
                    'started_at' => Carbon::now()->toDateTimeString(),
                    'ended_at' => Carbon::now()->addDays(31)->toDateTimeString()

                $payment = $this->me->payments()->create($data);

                $this->me->expired_at = $ended_at;

                Event::fire('Teeshot.Events.UserHasPurchased', new UserHasPurchased($this->me, $payment));


            return View::make('payments.inicis')->with(compact('inipay', 'payment'));

And, finally, the views:

1st view with options

2nd view which loads preview screen and brings in Active X encryption modules;

3rd view which shows the result;

I know there’re rooms to improve. But, hopefully, my codes here would eventually help you get you going with the INICIS PG service without pulling your hair out. Even though I followed their instructions to load the JavaScript file written in UTF-8 Korean code. Their server isn’t smart enough to figure I’m using UTF-8. This is the level of service from a company called themselves number 1 in Korea. guess they’re all too busy doing shit.