Complete donation page front-end and base payment operations

master
Uğur Arıcı 5 years ago
parent ba36b3851e
commit 4653cf74a2
  1. 3
      .env.example
  2. 100
      app/Http/Controllers/DonationController.php
  3. 8
      config/services.php
  4. 5
      package-lock.json
  5. 3
      package.json
  6. 2
      public/js/app.js
  7. 6
      public/js/app.js.LICENSE.txt
  8. 2
      public/mix-manifest.json
  9. 3
      resources/js/app.js
  10. 305
      resources/js/components/DonationCard.vue
  11. 3
      routes/web.php

@ -44,3 +44,6 @@ PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
IYZIPAY_API_KEY=
IYZIPAY_SECRET_KEY=

@ -6,8 +6,106 @@ use Illuminate\Http\Request;
class DonationController extends Controller
{
public function index(Request $request)
public function index()
{
return view('donate');
}
public function donate(Request $request)
{
// dd($request);
$request->validate([
"amount" => 'required|numeric',
"currency" => 'required|in:USD,EUR,TL',
"frequency" => 'required|in:once,monthly,annually',
"card_holder_name" => 'required|string|max:100',
"card_number" => 'required|digits_between:15,16',
"card_expire_month" => 'required|digits:2',
"card_expire_year" => 'required|digits:2',
"card_cvc" => 'required|digits_between:3,4',
"first_name" => 'required|string',
"last_name" => 'required|string',
"show_name" => 'nullable|boolean',
"email" => 'required|email',
"billing_contact_name" => 'required|string',
"billing_address" => 'required|string',
"billing_city" => 'required|string',
"billing_country" => 'required|string',
"billing_zipcode" => 'nullable|string',
]);
$iyzipayCurrencies = [
"USD" => \Iyzipay\Model\Currency::USD,
"EUR" => \Iyzipay\Model\Currency::EUR,
"TL" => \Iyzipay\Model\Currency::TL,
];
$options = new \Iyzipay\Options();
$options->setBaseUrl(config("services.iyzipay.base_url"));
$options->setApiKey(config("services.iyzipay.api_key"));
$options->setSecretKey(config("services.iyzipay.secret_key"));
$paymentRequest = new \Iyzipay\Request\CreatePaymentRequest();
$paymentRequest->setLocale(\Iyzipay\Model\Locale::EN);
$paymentRequest->setConversationId(\Str::random(6));
$paymentRequest->setPrice($request->amount);
$paymentRequest->setPaidPrice($request->amount);
$paymentRequest->setCurrency($iyzipayCurrencies[$request->currency]);
$paymentRequest->setInstallment(1);
$paymentRequest->setPaymentChannel(\Iyzipay\Model\PaymentChannel::WEB);
$paymentRequest->setPaymentGroup(\Iyzipay\Model\PaymentGroup::SUBSCRIPTION);
$paymentCard = new \Iyzipay\Model\PaymentCard();
$paymentCard->setCardHolderName($request->card_holder_name);
$paymentCard->setCardNumber($request->card_number);
$paymentCard->setExpireMonth($request->card_expire_month);
$paymentCard->setExpireYear("20" . $request->card_expire_year);
$paymentCard->setCvc($request->card_cvc);
if ($request->frequency !== "once") {
$paymentCard->setRegisterCard(1);
}
$paymentRequest->setPaymentCard($paymentCard);
$buyer = new \Iyzipay\Model\Buyer();
$buyer->setId(md5($request->email));
$buyer->setName($request->first_name);
$buyer->setSurname($request->last_name);
$buyer->setEmail($request->email);
$buyer->setIdentityNumber("11111111111");
$buyer->setRegistrationAddress($request->billing_address);
$buyer->setIp($request->ip());
$buyer->setCity($request->billing_city);
$buyer->setCountry($request->billing_country);
if ($request->billing_zipcode) {
$buyer->setZipCode($request->billing_zipcode);
}
$paymentRequest->setBuyer($buyer);
$billingAddress = new \Iyzipay\Model\Address();
$billingAddress->setContactName($request->billing_contact_name);
$billingAddress->setAddress($request->billing_address);
$billingAddress->setCity($request->billing_city);
$billingAddress->setCountry($request->billing_country);
if ($request->billing_zipcode) {
$billingAddress->setZipCode($request->billing_zipcode);
}
$paymentRequest->setBillingAddress($billingAddress);
$basketItems = array();
$basketItem = new \Iyzipay\Model\BasketItem();
$basketItem->setId("donation-" . $request->frequency);
$basketItem->setName("Donation - " . $request->frequency);
$basketItem->setCategory1("Donation");
$basketItem->setCategory2($request->frequency);
$basketItem->setItemType(\Iyzipay\Model\BasketItemType::VIRTUAL);
$basketItem->setPrice($request->amount);
$basketItems[] = $basketItem;
$paymentRequest->setBasketItems($basketItems);
$payment = \Iyzipay\Model\Payment::create($paymentRequest, $options);
dd($payment);
}
}

@ -12,7 +12,7 @@ return [
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
@ -30,4 +30,10 @@ return [
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'iyzipay' => [
'base_url' => env('IYZIPAY_BASE_URL'),
'api_key' => env('IYZIPAY_API_KEY'),
'secret_key' => env('IYZIPAY_SECRET_KEY'),
],
];

5
package-lock.json generated

@ -9057,6 +9057,11 @@
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==",
"dev": true
},
"vue-credit-card-validation": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/vue-credit-card-validation/-/vue-credit-card-validation-0.1.8.tgz",
"integrity": "sha512-71ZqC9ts1ZE0Li4F+SqzPOeGxU+B/D5FhnPVGbUNj6YJTtLhyjzoyVEtGOB18TLdGBsa4CtWCtFzOwqPUWFhng=="
},
"vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",

@ -22,5 +22,8 @@
"sass-loader": "^8.0.0",
"vue": "^2.5.17",
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"vue-credit-card-validation": "^0.1.8"
}
}

File diff suppressed because one or more lines are too long

@ -35,6 +35,12 @@
* Date: 2020-05-04T22:49Z
*/
/*!
* vue-credit-card-validation v0.1.7
* (c) 2020 Michael Wuori
* Released under the MIT License.
*/
/**
* @license
* Lodash <https://lodash.com/>

@ -1,4 +1,4 @@
{
"/js/app.js": "/js/app.js?id=752a125965afecb67512",
"/js/app.js": "/js/app.js?id=d309ac63e39e34e21835",
"/css/app.css": "/css/app.css?id=36412c9f34a08f26af3c"
}

@ -7,6 +7,9 @@
require('./bootstrap');
window.Vue = require('vue');
import VueCardFormat from 'vue-credit-card-validation';
Vue.use(VueCardFormat);
/**
* The following block of code may be used to automatically register your

@ -1,9 +1,12 @@
<template>
<div class="card">
<div class="card-header">Donate</div>
<div class="card-body">
<form method="POST" action>
<div class="form-group row mb-0">
<div class="col-12">
<h1>Donate</h1>
</div>
</div>
<form method="POST" action="/make-donation">
<div class="form-group row">
<label for="currency" class="col-md-4 col-form-label text-md-right">Donation currency</label>
@ -30,7 +33,7 @@
type="button"
class="btn btn-block"
:class="{'btn-primary':frequency==frequencyItem.code, 'btn-outline-primary':frequency!=frequencyItem.code}"
@click="frequency=frequencyItem.code"
@click="setFrequency(frequencyItem.code)"
>{{frequencyItem.name}}</button>
</div>
</div>
@ -97,48 +100,287 @@
</div>
</div>
</div>
<!-- <div class="form-group row">
<hr />
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<h2>Your Info</h2>
</div>
</div>
<div class="form-group row">
<label for="first_name" class="col-md-4 col-form-label text-md-right">First Name</label>
<div class="col-md-6">
<input
id="first_name"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="first_name"
value="John"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label for="last_name" class="col-md-4 col-form-label text-md-right">Last Name</label>
<div class="col-md-6">
<input
id="last_name"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="last_name"
value="Doe"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
name="show_name"
id="show_name"
value="1"
/>
<label class="form-check-label" for="show_name">Show my name on donors list</label>
</div>
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">E-Mail Address</label>
<div class="col-md-6">
<input
id="email"
type="email"
class="form-control is-invalid"
class="form-control"
name="email"
required
autocomplete="email"
autofocus
value="john@doe.comi"
/>
</div>
</div>
<hr />
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<h2>Credit Card Info</h2>
</div>
</div>
<div class="form-group row">
<label
for="card_holder_name"
class="col-md-4 col-form-label text-md-right"
>Card Holder Name</label>
<div class="col-md-6">
<input
id="card_holder_name"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="card_holder_name"
value="John Doe"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label for="card_number" class="col-md-4 col-form-label text-md-right">Credit Card Number</label>
<div class="col-md-6">
<input
id="card_number"
type="tel"
class="form-control"
:class="{'is-invalid':1==0}"
name="card_number"
required
minlength="15"
maxlength="16"
autocomplete="off"
placeholder="################"
value="5400010000000004"
v-cardformat:restrictNumeric
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label
for="card_expire_month"
class="col-md-4 col-form-label text-md-right"
>Credit Card Expiration</label>
<div class="col-3">
<input
id="card_expire_month"
type="tel"
class="form-control"
:class="{'is-invalid':1==0}"
name="card_expire_month"
required
autocomplete="card_expire_month"
placeholder="MM"
minlength="2"
maxlength="2"
value="12"
v-cardformat:restrictNumeric
/>
</div>
<div class="col-3">
<input
id="card_expire_year"
type="tel"
class="form-control"
:class="{'is-invalid':1==0}"
name="card_expire_year"
required
autocomplete="card_expire_year"
placeholder="YY"
minlength="2"
maxlength="2"
value="30"
v-cardformat:restrictNumeric
/>
</div>
</div>
<div class="form-group row">
<label for="card_cvc" class="col-md-4 col-form-label text-md-right">Credit Card CVC</label>
<div class="col-md-3">
<input
id="card_cvc"
type="tel"
class="form-control"
:class="{'is-invalid':1==0}"
name="card_cvc"
required
autocomplete="card_cvc"
placeholder="***"
minlength="3"
maxlength="4"
value="123"
v-cardformat:restrictNumeric
/>
<span class="invalid-feedback" role="alert">
</div>
</div>
<hr />
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<h2>Billing Address</h2>
</div>
</div>
<div class="form-group row">
<label
for="billing_contact_name"
class="col-md-4 col-form-label text-md-right"
>Contact Name</label>
<div class="col-md-6">
<input
id="billing_contact_name"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="billing_contact_name"
value="John Doe"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label for="billing_address" class="col-md-4 col-form-label text-md-right">Address</label>
<div class="col-md-6">
<input
id="billing_address"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="billing_address"
value="Freedom St. 18/7"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">Password</label>
<label for="billing_city" class="col-md-4 col-form-label text-md-right">City</label>
<div class="col-md-6">
<input
id="password"
type="password"
id="billing_city"
type="text"
class="form-control"
name="password"
:class="{'is-invalid':1==0}"
name="billing_city"
value="Istanbul"
required
autocomplete="current-password"
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<label for="billing_country" class="col-md-4 col-form-label text-md-right">Country</label>
<div class="col-md-6">
<input
id="billing_country"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="billing_country"
value="Turkey"
required
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" />
<label class="form-check-label" for="remember">Remember Me</label>
</div>
<label for="billing_zipcode" class="col-md-4 col-form-label text-md-right">
Zip Code
<small>optional</small>
</label>
<div class="col-md-3">
<input
id="billing_zipcode"
type="text"
class="form-control"
:class="{'is-invalid':1==0}"
name="billing_zipcode"
value
/>
<span class="invalid-feedback" role="alert" v-if="1==0">
<strong>Sample error</strong>
</span>
</div>
</div>-->
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
@ -147,6 +389,10 @@
<!-- <a class="btn btn-link" href="#">Forgot Your Password?</a> -->
</div>
</div>
<input type="hidden" name="amount" :value="amount" />
<input type="hidden" name="frequency" :value="frequency" />
<input type="hidden" name="currency" :value="currency" />
<input type="hidden" name="_token" :value="csrfToken" />
</form>
</div>
</div>
@ -156,6 +402,9 @@
export default {
data() {
return {
card_number: null,
card_expire_month: null,
card_expire_year: null,
currency: "USD",
frequency: "monthly",
donationPackage: 4,
@ -163,7 +412,7 @@ export default {
currencies: [
{ name: "USD", code: "USD", symbol: "$" },
{ name: "EUR", code: "EUR", symbol: "€" },
{ name: "TRY", code: "TRY", symbol: "₺" }
{ name: "TRY", code: "TL", symbol: "₺" }
],
frequencies: [
{ name: "once", code: "once" },
@ -232,12 +481,26 @@ export default {
text = text + "/yr";
}
return text;
},
csrfToken() {
return document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content");
}
},
methods: {
setFrequency(code) {
this.frequency = code;
this.setAmountByPackage();
},
setDonationPackage(id) {
this.donationPackage = id;
const itemIndex = this.donationPackages.findIndex(item => item.id === id);
this.setAmountByPackage();
},
setAmountByPackage() {
const itemIndex = this.donationPackages.findIndex(
item => item.id === this.donationPackage
);
if (itemIndex !== -1) {
if (this.frequency == "once") {
this.amount = this.donationPackages[itemIndex].once_amount;

@ -15,5 +15,6 @@ use Illuminate\Support\Facades\Route;
Auth::routes();
Route::get('/', 'DonationController@index')->name('donate');
Route::get('/', 'DonationController@index')->name('donation.form');
Route::post('/make-donation', 'DonationController@donate')->name('donation.make');
Route::get('/home', 'HomeController@index')->name('home');

Loading…
Cancel
Save