/** * Validates an inbound coupon, applies or adds an error * */ public function handleCoupon(ChargeModel &$model) { $code = $model->planCoupon; // See if we have a matching record anywhere $coupon = $this->_getCouponModelByCode($code); if ($coupon == false) { // Not a valid code // Add an error to the model $model->addError('planCoupon', Craft::t('Sorry, not a valid coupon code')); return $model; } $type = 'one-off'; if ($model->planIntervalCount >= 1) { $type = 'recurring'; } // Match to the paymentType if ($coupon->paymentType == 'recurring' and $type != 'recurring') { $model->addError('planCoupon', Craft::t('Sorry, this coupon can only be used on recurring payments')); return; } else { if ($coupon->paymentType == 'one-off' and $type != 'one-off') { $model->addError('planCoupon', Craft::t('Sorry, this coupon can only be used on one-time payments')); return; } } // We'll also need to branch // If the $type is recurring, the discount is dealt with direclty on Stripe's side, // if it's one-off, we have to do the leg work here if ($type == 'recurring') { // We have the planCoupon market attached to the model, // and we'll return here, and do the work later return; } // Only dealing with one-time coupons now. $baseAmount = $model->planAmount * 100; // @todo - temp fix $baseCurrency = $model->planCurrency; $discountAmount = 0; $finalAmount = $baseAmount; if ($coupon->couponType == 'percentage') { $percentageOff = $coupon->percentageOff; $discountAmount = (double) $baseAmount * ($percentageOff / 100); $finalAmount = (double) $baseAmount - $discountAmount; } if ($coupon->couponType == 'amount') { $amountOff = $coupon->amountOff; $discountAmount = $amountOff; $finalAmount = (double) $baseAmount - $amountOff; } // Sanity Check if ($discountAmount <= 0) { // nope, discount is zero. $model->addError('planCoupon', Craft::t('Sorry, this coupon is invalid')); return; } if ($finalAmount >= $baseAmount) { // nope, somehow this 'discount' has increased the price $model->addError('planCoupon', Craft::t('Sorry, this coupon is invalid')); return; } // Check we're still above the min transaction price if ($finalAmount <= 0.5) { $model->addError('planCoupon', Craft::t('Sorry, applying this coupon brings your total below the minimum we can charge')); return; } $finalAmount = strval($finalAmount) / 100; // @todo temp fix for coupons $discountAmount = strval($discountAmount); $model->planAmount = $finalAmount; $model->planDiscount = $discountAmount; $model->planFullAmount = $baseAmount; return; }