diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json
index a30f643..eaa8293 100644
--- a/assets/i18n/en-US.json
+++ b/assets/i18n/en-US.json
@@ -255,7 +255,7 @@
   "walletCurrencyPoints": "New Solar Points",
   "walletCurrencyShortPoints": "NSP",
   "walletCurrencyGolds": "The Solar Dollars",
-  "walletCurrencyShortGolds": "TSD",
+  "walletCurrencyShortGolds": "NSD",
   "retry": "Retry",
   "creatorHubUnselectedHint": "Pick / create a publisher to get started.",
   "relationships": "Relationships",
@@ -487,5 +487,31 @@
   "biometricAuthFailed": "Biometric authentication failed. Please try again.",
   "paymentSuccess": "Payment completed successfully!",
   "membershipPurchaseSuccess": "Membership purchased successfully!",
-  "paymentError": "Payment failed: {error}"
+  "paymentError": "Payment failed: {error}",
+  "usePinInstead": "Use PIN Code",
+  "levelProgress": "Level Progress",
+  "unlockedFeatures": "Unlocked Features",
+  "unlockedFeaturesDescription": "Features unlocked at your current level will be displayed here.",
+  "stellarMembership": "Stellar Membership",
+  "upgradeYourPlan": "Upgrade Your Plan",
+  "chooseYourPlan": "Choose Your Plan",
+  "currentMembership": "Current: {}",
+  "membershipExpires": "Expires: {}",
+  "membershipTierStellar": "Stellar",
+  "membershipTierNova": "Nova",
+  "membershipTierSupernova": "Supernova",
+  "membershipTierUnknown": "Unknown",
+  "membershipPriceStellar": "10 NS$ per month",
+  "membershipPriceNova": "20 NS$ per month",
+  "membershipPriceSupernova": "30 NS$ per month",
+  "membershipFeatureBasic": "Basic features",
+  "membershipFeaturePrioritySupport": "Priority support",
+  "membershipFeatureAdFree": "Ad-free experience",
+  "membershipFeatureAllPrimary": "All Primary features",
+  "membershipFeatureAdvancedCustomization": "Advanced customization",
+  "membershipFeatureEarlyAccess": "Early access",
+  "membershipFeatureAllNova": "All Nova features",
+  "membershipFeatureExclusiveContent": "Exclusive content",
+  "membershipFeatureVipSupport": "VIP support",
+  "membershipCurrentBadge": "CURRENT"
 }
diff --git a/assets/i18n/zh-TW.json b/assets/i18n/zh-TW.json
index 2f8e144..d74b8e4 100644
--- a/assets/i18n/zh-TW.json
+++ b/assets/i18n/zh-TW.json
@@ -307,5 +307,32 @@
   "chatBreakCleared": "聊天暫停已清除。",
   "chatBreakCustom": "自訂時長",
   "chatBreakEnterMinutes": "輸入分鐘數",
-  "chatBreakNone": "無"
+  "chatBreakNone": "無",
+  "paymentError": "付款失敗:{error}",
+  "usePinInstead": "使用密碼",
+  "levelProgress": "等級進度",
+  "unlockedFeatures": "已解鎖功能",
+  "unlockedFeaturesDescription": "您目前等級解鎖的功能將會顯示在此。",
+  "stellarMembership": "星際會員",
+  "upgradeYourPlan": "升級您的方案",
+  "chooseYourPlan": "選擇您的方案",
+  "currentMembership": "目前:{}",
+  "membershipExpires": "到期:{}",
+  "membershipTierStellar": "星際",
+  "membershipTierNova": "新星",
+  "membershipTierSupernova": "超新星",
+  "membershipTierUnknown": "未知",
+  "membershipPriceStellar": "每月 10 星幣",
+  "membershipPriceNova": "每月 20 星幣",
+  "membershipPriceSupernova": "每月 30 星幣",
+  "membershipFeatureBasic": "基本功能",
+  "membershipFeaturePrioritySupport": "優先支援",
+  "membershipFeatureAdFree": "無廣告體驗",
+  "membershipFeatureAllPrimary": "所有主要功能",
+  "membershipFeatureAdvancedCustomization": "進階自訂",
+  "membershipFeatureEarlyAccess": "搶先體驗",
+  "membershipFeatureAllNova": "所有新星功能",
+  "membershipFeatureExclusiveContent": "獨家內容",
+  "membershipFeatureVipSupport": "VIP 支援",
+  "membershipCurrentBadge": "目前"
 }
\ No newline at end of file
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 858ede3..caca9f0 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -74,6 +74,8 @@
 		<string>UIInterfaceOrientationLandscapeLeft</string>
 		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
+	<key>NSFaceIDUsageDescription</key>
+	<string>Allow the Solar Network verify your ownership of the logged in account and continue your action quickly.</string>
 	<key>NSUserActivityTypes</key>
 	<array>
 		<string>INStartCallIntent</string>
diff --git a/lib/models/wallet.dart b/lib/models/wallet.dart
index f2dd341..9083640 100644
--- a/lib/models/wallet.dart
+++ b/lib/models/wallet.dart
@@ -62,21 +62,21 @@ sealed class SnWalletSubscription with _$SnWalletSubscription {
   const factory SnWalletSubscription({
     required String id,
     required DateTime begunAt,
-    required DateTime endedAt,
+    required DateTime? endedAt,
     required String identifier,
-    required bool isActive,
-    required bool isFreeTrial,
-    required int status,
-    required String paymentMethod,
-    required Map<String, dynamic> paymentDetails,
-    required double basePrice,
+    @Default(true) bool isActive,
+    @Default(false) bool isFreeTrial,
+    @Default(1) int status,
+    required String? paymentMethod,
+    required Map<String, dynamic>? paymentDetails,
+    required double? basePrice,
     required String? couponId,
     required dynamic coupon,
-    required DateTime renewalAt,
+    required DateTime? renewalAt,
     required String accountId,
     required SnAccount? account,
-    required bool isAvailable,
-    required double finalPrice,
+    @Default(true) bool isAvailable,
+    required double? finalPrice,
     required DateTime createdAt,
     required DateTime updatedAt,
     required DateTime? deletedAt,
diff --git a/lib/models/wallet.freezed.dart b/lib/models/wallet.freezed.dart
index 2782f55..6f17011 100644
--- a/lib/models/wallet.freezed.dart
+++ b/lib/models/wallet.freezed.dart
@@ -562,7 +562,7 @@ $SnWalletCopyWith<$Res>? get payeeWallet {
 /// @nodoc
 mixin _$SnWalletSubscription {
 
- String get id; DateTime get begunAt; DateTime get endedAt; String get identifier; bool get isActive; bool get isFreeTrial; int get status; String get paymentMethod; Map<String, dynamic> get paymentDetails; double get basePrice; String? get couponId; dynamic get coupon; DateTime get renewalAt; String get accountId; SnAccount? get account; bool get isAvailable; double get finalPrice; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
+ String get id; DateTime get begunAt; DateTime? get endedAt; String get identifier; bool get isActive; bool get isFreeTrial; int get status; String? get paymentMethod; Map<String, dynamic>? get paymentDetails; double? get basePrice; String? get couponId; dynamic get coupon; DateTime? get renewalAt; String get accountId; SnAccount? get account; bool get isAvailable; double? get finalPrice; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 /// Create a copy of SnWalletSubscription
 /// with the given fields replaced by the non-null parameter values.
 @JsonKey(includeFromJson: false, includeToJson: false)
@@ -595,7 +595,7 @@ abstract mixin class $SnWalletSubscriptionCopyWith<$Res>  {
   factory $SnWalletSubscriptionCopyWith(SnWalletSubscription value, $Res Function(SnWalletSubscription) _then) = _$SnWalletSubscriptionCopyWithImpl;
 @useResult
 $Res call({
- String id, DateTime begunAt, DateTime endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String paymentMethod, Map<String, dynamic> paymentDetails, double basePrice, String? couponId, dynamic coupon, DateTime renewalAt, String accountId, SnAccount? account, bool isAvailable, double finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
+ String id, DateTime begunAt, DateTime? endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String? paymentMethod, Map<String, dynamic>? paymentDetails, double? basePrice, String? couponId, dynamic coupon, DateTime? renewalAt, String accountId, SnAccount? account, bool isAvailable, double? finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 });
 
 
@@ -612,26 +612,26 @@ class _$SnWalletSubscriptionCopyWithImpl<$Res>
 
 /// Create a copy of SnWalletSubscription
 /// with the given fields replaced by the non-null parameter values.
-@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = null,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = null,Object? paymentDetails = null,Object? basePrice = null,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = null,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
+@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = freezed,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = freezed,Object? paymentDetails = freezed,Object? basePrice = freezed,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = freezed,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
   return _then(_self.copyWith(
 id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
 as String,begunAt: null == begunAt ? _self.begunAt : begunAt // ignore: cast_nullable_to_non_nullable
-as DateTime,endedAt: null == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
-as DateTime,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
+as DateTime,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
+as DateTime?,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
 as String,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
 as bool,isFreeTrial: null == isFreeTrial ? _self.isFreeTrial : isFreeTrial // ignore: cast_nullable_to_non_nullable
 as bool,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
-as int,paymentMethod: null == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
-as String,paymentDetails: null == paymentDetails ? _self.paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
-as Map<String, dynamic>,basePrice: null == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
-as double,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
+as int,paymentMethod: freezed == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
+as String?,paymentDetails: freezed == paymentDetails ? _self.paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
+as Map<String, dynamic>?,basePrice: freezed == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
+as double?,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
 as String?,coupon: freezed == coupon ? _self.coupon : coupon // ignore: cast_nullable_to_non_nullable
-as dynamic,renewalAt: null == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
-as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
+as dynamic,renewalAt: freezed == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
+as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
 as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
 as SnAccount?,isAvailable: null == isAvailable ? _self.isAvailable : isAvailable // ignore: cast_nullable_to_non_nullable
-as bool,finalPrice: null == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
-as double,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
+as bool,finalPrice: freezed == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
+as double?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
 as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
 as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
 as DateTime?,
@@ -657,32 +657,34 @@ $SnAccountCopyWith<$Res>? get account {
 @JsonSerializable()
 
 class _SnWalletSubscription implements SnWalletSubscription {
-  const _SnWalletSubscription({required this.id, required this.begunAt, required this.endedAt, required this.identifier, required this.isActive, required this.isFreeTrial, required this.status, required this.paymentMethod, required final  Map<String, dynamic> paymentDetails, required this.basePrice, required this.couponId, required this.coupon, required this.renewalAt, required this.accountId, required this.account, required this.isAvailable, required this.finalPrice, required this.createdAt, required this.updatedAt, required this.deletedAt}): _paymentDetails = paymentDetails;
+  const _SnWalletSubscription({required this.id, required this.begunAt, required this.endedAt, required this.identifier, this.isActive = true, this.isFreeTrial = false, this.status = 1, required this.paymentMethod, required final  Map<String, dynamic>? paymentDetails, required this.basePrice, required this.couponId, required this.coupon, required this.renewalAt, required this.accountId, required this.account, this.isAvailable = true, required this.finalPrice, required this.createdAt, required this.updatedAt, required this.deletedAt}): _paymentDetails = paymentDetails;
   factory _SnWalletSubscription.fromJson(Map<String, dynamic> json) => _$SnWalletSubscriptionFromJson(json);
 
 @override final  String id;
 @override final  DateTime begunAt;
-@override final  DateTime endedAt;
+@override final  DateTime? endedAt;
 @override final  String identifier;
-@override final  bool isActive;
-@override final  bool isFreeTrial;
-@override final  int status;
-@override final  String paymentMethod;
- final  Map<String, dynamic> _paymentDetails;
-@override Map<String, dynamic> get paymentDetails {
+@override@JsonKey() final  bool isActive;
+@override@JsonKey() final  bool isFreeTrial;
+@override@JsonKey() final  int status;
+@override final  String? paymentMethod;
+ final  Map<String, dynamic>? _paymentDetails;
+@override Map<String, dynamic>? get paymentDetails {
+  final value = _paymentDetails;
+  if (value == null) return null;
   if (_paymentDetails is EqualUnmodifiableMapView) return _paymentDetails;
   // ignore: implicit_dynamic_type
-  return EqualUnmodifiableMapView(_paymentDetails);
+  return EqualUnmodifiableMapView(value);
 }
 
-@override final  double basePrice;
+@override final  double? basePrice;
 @override final  String? couponId;
 @override final  dynamic coupon;
-@override final  DateTime renewalAt;
+@override final  DateTime? renewalAt;
 @override final  String accountId;
 @override final  SnAccount? account;
-@override final  bool isAvailable;
-@override final  double finalPrice;
+@override@JsonKey() final  bool isAvailable;
+@override final  double? finalPrice;
 @override final  DateTime createdAt;
 @override final  DateTime updatedAt;
 @override final  DateTime? deletedAt;
@@ -720,7 +722,7 @@ abstract mixin class _$SnWalletSubscriptionCopyWith<$Res> implements $SnWalletSu
   factory _$SnWalletSubscriptionCopyWith(_SnWalletSubscription value, $Res Function(_SnWalletSubscription) _then) = __$SnWalletSubscriptionCopyWithImpl;
 @override @useResult
 $Res call({
- String id, DateTime begunAt, DateTime endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String paymentMethod, Map<String, dynamic> paymentDetails, double basePrice, String? couponId, dynamic coupon, DateTime renewalAt, String accountId, SnAccount? account, bool isAvailable, double finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
+ String id, DateTime begunAt, DateTime? endedAt, String identifier, bool isActive, bool isFreeTrial, int status, String? paymentMethod, Map<String, dynamic>? paymentDetails, double? basePrice, String? couponId, dynamic coupon, DateTime? renewalAt, String accountId, SnAccount? account, bool isAvailable, double? finalPrice, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 });
 
 
@@ -737,26 +739,26 @@ class __$SnWalletSubscriptionCopyWithImpl<$Res>
 
 /// Create a copy of SnWalletSubscription
 /// with the given fields replaced by the non-null parameter values.
-@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = null,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = null,Object? paymentDetails = null,Object? basePrice = null,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = null,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
+@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? begunAt = null,Object? endedAt = freezed,Object? identifier = null,Object? isActive = null,Object? isFreeTrial = null,Object? status = null,Object? paymentMethod = freezed,Object? paymentDetails = freezed,Object? basePrice = freezed,Object? couponId = freezed,Object? coupon = freezed,Object? renewalAt = freezed,Object? accountId = null,Object? account = freezed,Object? isAvailable = null,Object? finalPrice = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
   return _then(_SnWalletSubscription(
 id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
 as String,begunAt: null == begunAt ? _self.begunAt : begunAt // ignore: cast_nullable_to_non_nullable
-as DateTime,endedAt: null == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
-as DateTime,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
+as DateTime,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable
+as DateTime?,identifier: null == identifier ? _self.identifier : identifier // ignore: cast_nullable_to_non_nullable
 as String,isActive: null == isActive ? _self.isActive : isActive // ignore: cast_nullable_to_non_nullable
 as bool,isFreeTrial: null == isFreeTrial ? _self.isFreeTrial : isFreeTrial // ignore: cast_nullable_to_non_nullable
 as bool,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
-as int,paymentMethod: null == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
-as String,paymentDetails: null == paymentDetails ? _self._paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
-as Map<String, dynamic>,basePrice: null == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
-as double,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
+as int,paymentMethod: freezed == paymentMethod ? _self.paymentMethod : paymentMethod // ignore: cast_nullable_to_non_nullable
+as String?,paymentDetails: freezed == paymentDetails ? _self._paymentDetails : paymentDetails // ignore: cast_nullable_to_non_nullable
+as Map<String, dynamic>?,basePrice: freezed == basePrice ? _self.basePrice : basePrice // ignore: cast_nullable_to_non_nullable
+as double?,couponId: freezed == couponId ? _self.couponId : couponId // ignore: cast_nullable_to_non_nullable
 as String?,coupon: freezed == coupon ? _self.coupon : coupon // ignore: cast_nullable_to_non_nullable
-as dynamic,renewalAt: null == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
-as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
+as dynamic,renewalAt: freezed == renewalAt ? _self.renewalAt : renewalAt // ignore: cast_nullable_to_non_nullable
+as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
 as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
 as SnAccount?,isAvailable: null == isAvailable ? _self.isAvailable : isAvailable // ignore: cast_nullable_to_non_nullable
-as bool,finalPrice: null == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
-as double,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
+as bool,finalPrice: freezed == finalPrice ? _self.finalPrice : finalPrice // ignore: cast_nullable_to_non_nullable
+as double?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
 as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
 as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
 as DateTime?,
diff --git a/lib/models/wallet.g.dart b/lib/models/wallet.g.dart
index bba682c..a94d00c 100644
--- a/lib/models/wallet.g.dart
+++ b/lib/models/wallet.g.dart
@@ -106,24 +106,30 @@ _SnWalletSubscription _$SnWalletSubscriptionFromJson(
 ) => _SnWalletSubscription(
   id: json['id'] as String,
   begunAt: DateTime.parse(json['begun_at'] as String),
-  endedAt: DateTime.parse(json['ended_at'] as String),
+  endedAt:
+      json['ended_at'] == null
+          ? null
+          : DateTime.parse(json['ended_at'] as String),
   identifier: json['identifier'] as String,
-  isActive: json['is_active'] as bool,
-  isFreeTrial: json['is_free_trial'] as bool,
-  status: (json['status'] as num).toInt(),
-  paymentMethod: json['payment_method'] as String,
-  paymentDetails: json['payment_details'] as Map<String, dynamic>,
-  basePrice: (json['base_price'] as num).toDouble(),
+  isActive: json['is_active'] as bool? ?? true,
+  isFreeTrial: json['is_free_trial'] as bool? ?? false,
+  status: (json['status'] as num?)?.toInt() ?? 1,
+  paymentMethod: json['payment_method'] as String?,
+  paymentDetails: json['payment_details'] as Map<String, dynamic>?,
+  basePrice: (json['base_price'] as num?)?.toDouble(),
   couponId: json['coupon_id'] as String?,
   coupon: json['coupon'],
-  renewalAt: DateTime.parse(json['renewal_at'] as String),
+  renewalAt:
+      json['renewal_at'] == null
+          ? null
+          : DateTime.parse(json['renewal_at'] as String),
   accountId: json['account_id'] as String,
   account:
       json['account'] == null
           ? null
           : SnAccount.fromJson(json['account'] as Map<String, dynamic>),
-  isAvailable: json['is_available'] as bool,
-  finalPrice: (json['final_price'] as num).toDouble(),
+  isAvailable: json['is_available'] as bool? ?? true,
+  finalPrice: (json['final_price'] as num?)?.toDouble(),
   createdAt: DateTime.parse(json['created_at'] as String),
   updatedAt: DateTime.parse(json['updated_at'] as String),
   deletedAt:
@@ -137,7 +143,7 @@ Map<String, dynamic> _$SnWalletSubscriptionToJson(
 ) => <String, dynamic>{
   'id': instance.id,
   'begun_at': instance.begunAt.toIso8601String(),
-  'ended_at': instance.endedAt.toIso8601String(),
+  'ended_at': instance.endedAt?.toIso8601String(),
   'identifier': instance.identifier,
   'is_active': instance.isActive,
   'is_free_trial': instance.isFreeTrial,
@@ -147,7 +153,7 @@ Map<String, dynamic> _$SnWalletSubscriptionToJson(
   'base_price': instance.basePrice,
   'coupon_id': instance.couponId,
   'coupon': instance.coupon,
-  'renewal_at': instance.renewalAt.toIso8601String(),
+  'renewal_at': instance.renewalAt?.toIso8601String(),
   'account_id': instance.accountId,
   'account': instance.account?.toJson(),
   'is_available': instance.isAvailable,
diff --git a/lib/screens/account/leveling.dart b/lib/screens/account/leveling.dart
index 116e7dc..030d883 100644
--- a/lib/screens/account/leveling.dart
+++ b/lib/screens/account/leveling.dart
@@ -9,6 +9,7 @@ import 'package:island/models/wallet.dart';
 import 'package:island/pods/network.dart';
 import 'package:island/pods/userinfo.dart';
 import 'package:island/services/responsive.dart';
+import 'package:island/services/time.dart';
 import 'package:island/widgets/account/leveling_progress.dart';
 import 'package:island/widgets/alert.dart';
 import 'package:island/widgets/app_scaffold.dart';
@@ -51,7 +52,7 @@ class LevelingScreen extends HookConsumerWidget {
 
             // Level Stairs Graph
             Text(
-              'Level Progress',
+              'levelProgress'.tr(),
               style: Theme.of(
                 context,
               ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
@@ -79,12 +80,12 @@ class LevelingScreen extends HookConsumerWidget {
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
                   Text(
-                    'Unlocked Features',
+                    'unlockedFeatures'.tr(),
                     style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                   ),
                   const Gap(8),
                   Text(
-                    'Features unlocked at your current level will be displayed here.',
+                    'unlockedFeaturesDescription'.tr(),
                     style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                       color: Theme.of(context).colorScheme.onSurfaceVariant,
                     ),
@@ -252,7 +253,7 @@ class LevelingScreen extends HookConsumerWidget {
               ),
               const Gap(8),
               Text(
-                'Stellar Membership',
+                'stellarMembership'.tr(),
                 style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
               ),
             ],
@@ -265,7 +266,7 @@ class LevelingScreen extends HookConsumerWidget {
           ],
 
           Text(
-            isActive ? 'Upgrade Your Plan' : 'Choose Your Plan',
+            isActive ? 'upgradeYourPlan'.tr() : 'chooseYourPlan'.tr(),
             style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
           ),
           const Gap(12),
@@ -299,19 +300,20 @@ class LevelingScreen extends HookConsumerWidget {
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 Text(
-                  'Current: $tierName',
+                  'currentMembership'.tr(args: [tierName]),
                   style: TextStyle(
                     fontSize: 14,
                     fontWeight: FontWeight.w600,
                     color: tierColor,
                   ),
                 ),
-                Text(
-                  'Expires: ${_formatDate(membership.endedAt)}',
-                  style: Theme.of(context).textTheme.bodySmall?.copyWith(
-                    color: Theme.of(context).colorScheme.onSurfaceVariant,
+                if (membership.endedAt != null)
+                  Text(
+                    'membershipExpires'.tr(args: [membership.endedAt!.formatSystem()]),
+                    style: Theme.of(context).textTheme.bodySmall?.copyWith(
+                      color: Theme.of(context).colorScheme.onSurfaceVariant,
+                    ),
                   ),
-                ),
               ],
             ),
           ),
@@ -328,31 +330,31 @@ class LevelingScreen extends HookConsumerWidget {
     final tiers = [
       {
         'id': 'solian.stellar.primary',
-        'name': 'Stellar',
-        'price': '10 NS\$ per month',
+        'name': 'membershipTierStellar'.tr(),
+        'price': 'membershipPriceStellar'.tr(),
         'features': [
-          'Basic features',
-          'Priority support',
-          'Ad-free experience',
+          'membershipFeatureBasic'.tr(),
+          'membershipFeaturePrioritySupport'.tr(),
+          'membershipFeatureAdFree'.tr(),
         ],
         'color': Colors.blue,
       },
       {
         'id': 'solian.stellar.nova',
-        'name': 'Nova',
-        'price': '20 NS\$ per month',
+        'name': 'membershipTierNova'.tr(),
+        'price': 'membershipPriceNova'.tr(),
         'features': [
-          'All Primary features',
-          'Advanced customization',
-          'Early access',
+          'membershipFeatureAllPrimary'.tr(),
+          'membershipFeatureAdvancedCustomization'.tr(),
+          'membershipFeatureEarlyAccess'.tr(),
         ],
         'color': Colors.purple,
       },
       {
         'id': 'solian.stellar.supernova',
-        'name': 'Supernova',
-        'price': '30 NS\$ per month',
-        'features': ['All Nova features', 'Exclusive content', 'VIP support'],
+        'name': 'membershipTierSupernova'.tr(),
+        'price': 'membershipPriceSupernova'.tr(),
+        'features': ['membershipFeatureAllNova'.tr(), 'membershipFeatureExclusiveContent'.tr(), 'membershipFeatureVipSupport'.tr()],
         'color': Colors.orange,
       },
     ];
@@ -432,7 +434,7 @@ class LevelingScreen extends HookConsumerWidget {
                                         borderRadius: BorderRadius.circular(4),
                                       ),
                                       child: Text(
-                                        'CURRENT',
+                                        'membershipCurrentBadge'.tr(),
                                         style: TextStyle(
                                           fontSize: 10,
                                           fontWeight: FontWeight.bold,
@@ -476,13 +478,13 @@ class LevelingScreen extends HookConsumerWidget {
   String _getMembershipTierName(String identifier) {
     switch (identifier) {
       case 'solian.stellar.primary':
-        return 'Primary';
+        return 'membershipTierStellar'.tr();
       case 'solian.stellar.nova':
-        return 'Nova';
+        return 'membershipTierNova'.tr();
       case 'solian.stellar.supernova':
-        return 'Supernova';
+        return 'membershipTierSupernova'.tr();
       default:
-        return 'Unknown';
+        return 'membershipTierUnknown'.tr();
     }
   }
 
@@ -499,10 +501,6 @@ class LevelingScreen extends HookConsumerWidget {
     }
   }
 
-  String _formatDate(DateTime date) {
-    return '${date.day}/${date.month}/${date.year}';
-  }
-
   Future<void> _purchaseMembership(
     BuildContext context,
     WidgetRef ref,
@@ -538,21 +536,23 @@ class LevelingScreen extends HookConsumerWidget {
         enableBiometric: true,
       );
 
+      if (context.mounted) showLoadingModal(context);
+
       if (paidOrder != null) {
-        // Payment successful, refresh user info or show success message
-        ref.invalidate(userInfoProvider);
+        await client.post(
+          '/subscriptions/order/handle',
+          data: {'order_id': paidOrder.id},
+        );
+
+        ref.read(userInfoProvider.notifier).fetchUser();
         if (context.mounted) {
-          ScaffoldMessenger.of(context).showSnackBar(
-            SnackBar(
-              content: Text('membershipPurchaseSuccess'.tr()),
-              backgroundColor: Theme.of(context).colorScheme.primary,
-            ),
-          );
+          showSnackBar(context, 'membershipPurchaseSuccess'.tr());
         }
       }
     } catch (err) {
-      if (context.mounted) hideLoadingModal(context);
       showErrorAlert(err);
+    } finally {
+      if (context.mounted) hideLoadingModal(context);
     }
   }
 }
diff --git a/lib/widgets/payment/payment_overlay.dart b/lib/widgets/payment/payment_overlay.dart
index b6648c5..0958907 100644
--- a/lib/widgets/payment/payment_overlay.dart
+++ b/lib/widgets/payment/payment_overlay.dart
@@ -12,6 +12,7 @@ import 'package:dio/dio.dart';
 import 'package:local_auth/local_auth.dart';
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
 import 'package:flutter/services.dart';
+import 'package:styled_widget/styled_widget.dart';
 
 class PaymentOverlay extends HookConsumerWidget {
   final SnWalletOrder order;
@@ -278,12 +279,7 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
       _isPinMode = true;
     });
     if (message != null && message.isNotEmpty) {
-      ScaffoldMessenger.of(context).showSnackBar(
-        SnackBar(
-          content: Text(message),
-          backgroundColor: Theme.of(context).colorScheme.error,
-        ),
-      );
+      showSnackBar(context, message);
     }
   }
 
@@ -423,21 +419,10 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
   Widget _buildBiometricAuth() {
     return Column(
       mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
       children: [
-        Container(
-          width: 120,
-          height: 120,
-          decoration: BoxDecoration(
-            color: Theme.of(context).colorScheme.primaryContainer,
-            shape: BoxShape.circle,
-          ),
-          child: Icon(
-            Symbols.fingerprint,
-            size: 64,
-            color: Theme.of(context).colorScheme.onPrimaryContainer,
-          ),
-        ),
-        const Gap(24),
+        Icon(Symbols.fingerprint, size: 48),
+        const Gap(16),
         Text(
           'useBiometricToConfirm'.tr(),
           style: Theme.of(
@@ -445,15 +430,15 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
           ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w500),
           textAlign: TextAlign.center,
         ),
-        const Gap(16),
         Text(
-          'touchSensorToAuthenticate'.tr(),
+          'The biometric data will only be processed on your device',
           style: Theme.of(context).textTheme.bodyMedium?.copyWith(
             color: Theme.of(context).colorScheme.onSurfaceVariant,
+            fontSize: 11,
           ),
           textAlign: TextAlign.center,
-        ),
-        const Gap(32),
+        ).opacity(0.75),
+        const Gap(28),
         ElevatedButton.icon(
           onPressed: _authenticateWithBiometric,
           icon: const Icon(Symbols.fingerprint),
@@ -462,13 +447,12 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
             padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
           ),
         ),
-        const Gap(16),
         TextButton(
           onPressed: () => _fallbackToPinMode(null),
           child: Text('usePinInstead'.tr()),
         ),
       ],
-    );
+    ).center();
   }
 
   Widget _buildActionButtons() {