total->currency(); foreach ( [ $this->subtotal, $this->discount, $this->tax, $this->due_now, $this->due_later ] as $m ) { if ( $m->currency() !== $currency ) { throw new DomainException( 'pricing.totals_currency', 'All OrderTotals money fields must share a currency.' ); } } foreach ( [ $this->subtotal, $this->discount, $this->tax, $this->total, $this->due_now, $this->due_later ] as $m ) { if ( $m->is_negative() ) { throw new DomainException( 'pricing.totals_negative', 'OrderTotals money fields must not be negative.' ); } } if ( $this->due_now->amount_minor() + $this->due_later->amount_minor() !== $this->total->amount_minor() ) { throw new DomainException( 'pricing.totals_due_split', 'due_now + due_later must equal total.' ); } } /** * Subtotal before discount. * * @since 0.1.0 */ public function subtotal(): Money { return $this->subtotal; } /** * Discount amount. * * @since 0.1.0 */ public function discount(): Money { return $this->discount; } /** * Tax component. * * @since 0.1.0 */ public function tax(): Money { return $this->tax; } /** * Grand total. * * @since 0.1.0 */ public function total(): Money { return $this->total; } /** * Amount due now. * * @since 0.1.0 */ public function due_now(): Money { return $this->due_now; } /** * Amount due later. * * @since 0.1.0 */ public function due_later(): Money { return $this->due_later; } /** * JSON payload stored on the order intent (docs/11 §3). * * @return array{ * subtotal_minor: int, * discount_minor: int, * tax_minor: int, * total_minor: int, * due_now_minor: int, * due_later_minor: int, * currency: string * } */ public function to_payload(): array { return [ 'subtotal_minor' => $this->subtotal->amount_minor(), 'discount_minor' => $this->discount->amount_minor(), 'tax_minor' => $this->tax->amount_minor(), 'total_minor' => $this->total->amount_minor(), 'due_now_minor' => $this->due_now->amount_minor(), 'due_later_minor' => $this->due_later->amount_minor(), 'currency' => $this->total->currency(), ]; } }