Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
v1.0.0-beta.5
Browse files Browse the repository at this point in the history
  • Loading branch information
kjmartens committed Nov 20, 2018
1 parent 7e1da2e commit 8a8cb79
Show file tree
Hide file tree
Showing 16 changed files with 365 additions and 102 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Solspace Freeform Payments Changelog

## 1.0.0-beta.5 - 2018-11-20
### Changed
- Updated Stripe settings to allow both LIVE and TEST keys to allow for easy switching into test mode.
- Improved built in error handling on credit card fields in forms.

### Fixed
- Fixed a bug where Payments would send a 400 error on subsequent recurring payment transactions.

## 1.0.0-beta.4 - 2018-11-12
### Changed
- Updated Freeform to detect if more than 1 form is loading Payments-enabled forms on the same page, and only load Stripe JS once.
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "solspace/craft3-freeform-payments",
"description": "Adds payment capabilities to Freeform.",
"version": "1.0.0-beta.4",
"version": "1.0.0-beta.5",
"type": "craft-plugin",
"authors": [
{
Expand All @@ -22,7 +22,7 @@
}
},
"extra": {
"schemaVersion": "1.0.0",
"schemaVersion": "1.0.2",
"handle": "freeform-payments",
"class": "Solspace\\FreeformPayments\\FreeformPayments",
"name": "Freeform Payments",
Expand Down
50 changes: 33 additions & 17 deletions src/Controllers/WebhooksController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function actionStripe()
$request = \Craft::$app->request;
$payload = $request->getRawBody();
$integrationId = $request->getQueryParam('id');
/** @var Stripe $integration */
$integration = $this->getPaymentGatewaysService()->getIntegrationObjectById($integrationId);

if (!$integration) {
Expand All @@ -45,34 +46,21 @@ public function actionStripe()

//TODO: implement all notification service call as events?
//TODO: update payment/subscription status accordingly
$errorMessage = FreeformPayments::t('Event is not linked to freeform submission');
switch ($event->type) {
case Event::CHARGE_SUCCEEDED:
$submissionId = $event->data->object->metadata->submission;
if (!$submissionId) {
throw new HttpException(400, $errorMessage);
}
$submissionId = $this->getSubmissionIdFromStripeEvent($event, $integration);
$this->getPaymentsNotificationService()->sendChargeSucceeded($submissionId);
break;
case Event::CHARGE_FAILED:
$submissionId = $event->data->object->metadata->submission;
if (!$submissionId) {
throw new HttpException(400, $errorMessage);
}
$submissionId = $this->getSubmissionIdFromStripeEvent($event, $integration);
$this->getPaymentsNotificationService()->sendChargeFailed($submissionId);
break;
case Event::CUSTOMER_SUBSCRIPTION_CREATED:
$submissionId = $event->data->object->metadata->submission;
if (!$submissionId) {
throw new HttpException(400, $errorMessage);
}
$submissionId = $this->getSubmissionIdFromStripeEvent($event, $integration);
$this->getPaymentsNotificationService()->sendSubscriptionCreated($submissionId);
break;
case Event::CUSTOMER_SUBSCRIPTION_DELETED:
$submissionId = $event->data->object->metadata->submission;
if (!$submissionId) {
throw new HttpException(400, $errorMessage);
}
$submissionId = $this->getSubmissionIdFromStripeEvent($event, $integration);
$this->getPaymentsNotificationService()->sendSubscriptionEnded($submissionId);
break;
case Event::INVOICE_PAYMENT_SUCCEEDED:
Expand All @@ -98,4 +86,32 @@ public function actionStripe()

return '';
}

/**
* @param Event $event
* @param Stripe $integration
*
* @return mixed
* @throws HttpException
*/
private function getSubmissionIdFromStripeEvent(Event $event, Stripe $integration)
{
$submissionId = $event->data->object->metadata->submission;
if ($submissionId) {
return $submissionId;
}

$subscriptionId = $event->data->object->source->metadata->subscription;
if ($subscriptionId) {
$subscription = $integration->getSubscriptionDetails($subscriptionId);

if (isset($subscription['metadata']['submission'])) {
return $subscription['metadata']['submission'];
}
}

$errorMessage = FreeformPayments::t('Event is not linked to freeform submission');

throw new HttpException(400, $errorMessage);
}
}
85 changes: 73 additions & 12 deletions src/Integrations/PaymentGateways/Stripe.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@

class Stripe extends AbstractPaymentGatewayIntegration
{
const SETTING_PUBLIC_KEY = 'public_key';
const SETTING_SECRET_KEY = 'secret_key';
const SETTING_WEBHOOK_KEY = 'webhook_key';
const SETTING_PUBLIC_KEY_LIVE = 'public_key_live';
const SETTING_SECRET_KEY_LIVE = 'secret_key_live';
const SETTING_PUBLIC_KEY_TEST = 'public_key_test';
const SETTING_SECRET_KEY_TEST = 'secret_key_test';
const SETTING_LIVE_MODE = 'live_mode';
const SETTING_WEBHOOK_KEY = 'webhook_key';

const TITLE = 'Stripe';
const LOG_CATEGORY = 'Stripe';
Expand Down Expand Up @@ -87,6 +90,7 @@ public static function fromStripeAmount($amount, $currency)
public static function fromStripeInterval($interval, $intervalCount)
{
$stripeInterval = ['interval' => $interval, 'count' => $intervalCount];

return array_search($stripeInterval, self::PLAN_INTERVAL_CONVERSION);
}

Expand All @@ -101,18 +105,39 @@ public static function getSettingBlueprints(): array
return [
new SettingBlueprint(
SettingBlueprint::TYPE_TEXT,
self::SETTING_PUBLIC_KEY,
'Public Key',
'Enter your Stripe public key here.',
self::SETTING_PUBLIC_KEY_LIVE,
'Public Key (Live)',
'Enter your Stripe LIVE public key here.',
true
),
new SettingBlueprint(
SettingBlueprint::TYPE_TEXT,
self::SETTING_SECRET_KEY_LIVE,
'Secret Key (Live)',
'Enter your Stripe LIVE secret key here.',
true
),
new SettingBlueprint(
SettingBlueprint::TYPE_TEXT,
self::SETTING_SECRET_KEY,
'Secret Key',
'Enter your Stripe secret key here.',
self::SETTING_PUBLIC_KEY_TEST,
'Public Key (Test)',
'Enter your Stripe TEST public key here.',
true
),
new SettingBlueprint(
SettingBlueprint::TYPE_TEXT,
self::SETTING_SECRET_KEY_TEST,
'Secret Key (Test)',
'Enter your Stripe TEST secret key here.',
true
),
new SettingBlueprint(
SettingBlueprint::TYPE_BOOL,
self::SETTING_LIVE_MODE,
'LIVE mode',
'Enable this to start using LIVE public and secret keys.',
false
),
new SettingBlueprint(
SettingBlueprint::TYPE_TEXT,
self::SETTING_WEBHOOK_KEY,
Expand Down Expand Up @@ -159,7 +184,9 @@ public function checkConnection(): bool
*/
public function fetchAccessToken(): string
{
return $this->getSetting(self::SETTING_SECRET_KEY);
return $this->getSetting(
$this->isLiveMode() ? self::SETTING_SECRET_KEY_LIVE :self::SETTING_SECRET_KEY_TEST
);
}

/**
Expand Down Expand Up @@ -532,6 +559,7 @@ public function getChargeDetails($id)
*/
public function getSubscriptionDetails($id)
{
$this->prepareApi();
try {
$subscription = StripeAPI\Subscription::retrieve($id);
} catch (\Exception $e) {
Expand All @@ -553,7 +581,11 @@ public function getSubscriptionDetails($id)
*/
public function onBeforeSave(IntegrationStorageInterface $model)
{
$model->updateAccessToken($this->getSetting(self::SETTING_SECRET_KEY));
$model->updateAccessToken(
$this->getSetting(
$this->isLiveMode() ? self::SETTING_SECRET_KEY_LIVE :self::SETTING_SECRET_KEY_TEST
)
);
}

/**
Expand Down Expand Up @@ -586,6 +618,27 @@ public function getExternalDashboardLink(string $resourceId, string $type): stri
}
}

/**
* @return string
* @throws IntegrationException
*/
public function getPublicKey(): string
{
return $this->getSetting(
$this->isLiveMode() ? self::SETTING_PUBLIC_KEY_LIVE : self::SETTING_PUBLIC_KEY_TEST
);
}


/**
* @return bool
* @throws IntegrationException
*/
protected function isLiveMode(): bool
{
return $this->getSetting(self::SETTING_LIVE_MODE);
}

/**
* @param $params
*
Expand Down Expand Up @@ -761,6 +814,10 @@ protected function savePayment($data, int $submissionId)
$model->currency = $data['currency'];
$model->last4 = $data['source']['card']['last4'];
$model->status = $data['paid'] ? PaymentRecord::STATUS_PAID : PaymentRecord::STATUS_FAILED;
$model->metadata = [
'chargeId' => $data['id'],
'card' => $data['source']['card'],
];
}

$handler->save($model);
Expand Down Expand Up @@ -812,7 +869,11 @@ protected function saveSubscription($data, int $submissionId, string $planResour
$model->currency = $data['plan']['currency'];
$model->interval = $data['plan']['interval'];
if (isset($data['source'])) {
$model->last4 = $data['source']['card']['last4'];
$model->last4 = $data['source']['card']['last4'];
$model->metadata = [
'chargeId' => $data['id'],
'card' => $data['source']['card'],
];
}
$model->status = $data['status'];
}
Expand Down
10 changes: 8 additions & 2 deletions src/Models/AbstractPaymentModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace Solspace\FreeformPayments\Models;

use craft\base\Model;
use Solspace\Freeform\Library\Payments\PaymentInterface;
use Solspace\Freeform\Freeform;
use Solspace\Freeform\Library\Integrations\PaymentGateways\PaymentGatewayIntegrationInterface;
use Solspace\Freeform\Library\Payments\PaymentInterface;

abstract class AbstractPaymentModel extends Model implements PaymentInterface
{
Expand All @@ -30,6 +30,9 @@ abstract class AbstractPaymentModel extends Model implements PaymentInterface
/** @var string */
public $errorMessage;

/** @var array */
public $metadata;

public $dateCreated;
public $dateUpdated;
public $uid;
Expand All @@ -55,7 +58,7 @@ abstract public function getType(): string;
public function getIntegration()
{
if (!$this->integration) {
$paymentGateways = Freeform::getInstance()->paymentGateways;
$paymentGateways = Freeform::getInstance()->paymentGateways;
$this->integration = $paymentGateways->getIntegrationObjectById($this->integrationId);
}

Expand All @@ -73,6 +76,7 @@ public function getIntegrationName(): string
if (!$integration) {
return '';
}

return $integration->getName();
}

Expand All @@ -87,6 +91,7 @@ public function getServiceProvider(): string
if (!$integration) {
return '';
}

return $integration->getServiceProvider();
}

Expand All @@ -99,6 +104,7 @@ public function getExternalDashboardLink(): string
if (!$integration || !$this->resourceId) {
return '';
}

return $integration->getExternalDashboardLink($this->resourceId, $this->getType());
}

Expand Down
9 changes: 0 additions & 9 deletions src/Models/PaymentModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,4 @@ public function getType(): string
{
return PaymentInterface::TYPE_SINGLE;
}

/**
* @return array
*/
public function rules(): array
{
return [
];
}
}
3 changes: 3 additions & 0 deletions src/Models/SubscriptionModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class SubscriptionModel extends AbstractPaymentModel
/** @var string */
public $interval;

/** @var int */
public $intervalCount;

/** @var int */
public $last4;

Expand Down
27 changes: 19 additions & 8 deletions src/Records/PaymentRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,26 @@

namespace Solspace\FreeformPayments\Records;

use craft\db\ActiveRecord;
use Solspace\Commons\Records\SerializableActiveRecord;
use Solspace\Freeform\Elements\Submission;
use Solspace\Freeform\Records\IntegrationRecord;
use yii\db\ActiveQuery;
use Solspace\Freeform\Elements\Submission;

/**
* @property string $id
* @property int $submissionId
* @property int $integrationId
* @property int $subscriptionId
* @property int $submissionId
* @property int $integrationId
* @property int $subscriptionId
* @property string $resourceId
* @property float $amount
* @property float $amount
* @property string $currency
* @property int $last4
* @property int $last4
* @property string $status
* @property string $metadata
* @property string $errorCode
* @property string $errorMessage
*/
class PaymentRecord extends ActiveRecord
class PaymentRecord extends SerializableActiveRecord
{
const TABLE = '{{%freeform_payments_payments}}';

Expand Down Expand Up @@ -70,4 +71,14 @@ public function getSubscription(): ActiveQuery
{
return $this->hasOne(SubscriptionRecord::TABLE, ['subscriptionId' => 'id']);
}

/**
* @inheritDoc
*/
protected function getSerializableFields(): array
{
return [
'metadata',
];
}
}
Loading

0 comments on commit 8a8cb79

Please sign in to comment.