fix(rider): البحث عن مكان والمحفظة الحقيقية وأسماء الخريطة
## البحث لم يكن يستجيب — غلافان مختلفان
مثبت بـcurl: /geocoding/search يرجّع {"results":[…]} بينما /geocoding/reverse
يرجّع مصفوفة عارية. افترضتُ كليهما مصفوفة، فكان البحث يفشل صامتاً — ولهذا
«تحديد من الخريطة» يعمل (يستعمل reverse) والبحث لا. أُضيفت رسالة «لا نتائج»
كي لا يبقى الفراغ غامضاً، وأيقونة لكل صنف مكان.
## المحفظة صارت دفعاً حقيقياً لا كاش-إن
كنت أستعمل POST /wallet/topup — وهو بوصف الخادم كاش-إن تجريبي يزيد الرصيد
بلا دفع. المسار الصحيح موجود أصلاً: POST /payments/charge مع provider
وpurpose، وسجلّ بوابات فيه cash · paymob · syriatel · mtn ومحوّل فاتورة
لـ cliq · shamcash · zaincash.
كليك وشام كاش وزين كاش تعمل بنمط **الفاتورة** — نفس ما يفعله سيرو حرفياً
(create_cliq_invoice.php): الخادم يولّد مرجعاً ويعرض حساب الاستلام، ويحوّل
المستخدم، والتسوية تصل لاحقاً بمطابقة رسالة المزوّد. لا بوابة تحويل حيّة.
- InvoiceSheet يعرض المرجع وحساب الاستلام بزرّي نسخ — الرقم يُحوَّل في تطبيق
بنك آخر فالنسخ ليس رفاهية
- يُقال صراحةً أن الرصيد لا يزيد الآن، قبل الضغط لا بعده
- حساب استلام غير مضبوط للمستأجر يُعرض كخطأ لا كتعليمات ناقصة
- أسماء المزوّدين صُحّحت لتطابق PaymentGatewayRegistry حرفياً (syriatel لا
syriatel_cash…) — أي اسم آخر يرجّع 400
- qi_card حُذف: لا محوّل له على الخادم
- السائق: chargeCredit بنيّة credit_topup للرصيد التشغيلي
## الخريطة وواجهة «إلى أين»
- أسماء البداية والنهاية تُرسم فوق الخريطة (نمط سيرو) كطبقة فلاتر لا marker
- البطاقة المطوية صارت حقل بحث بارزاً مع الموقع الحالي فوقه
- حقل البحث يفتح مركّزاً مع زرّ مسح
## أداة
tool/sync_from_rider.sh كان يستثني ملفَّي ARB فيُسقط كل مفتاح مشترك جديد
ويكسر بناء السائق — تكرّر ثلاث مرات. صارا يُنسخان ثم تُفرض نصوص السائق فوقهما.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e22cc5c7e4
commit
6a33cc7241
@@ -2,6 +2,33 @@ import '../../../core/api/api_client.dart';
|
||||
import 'models/wallet.dart';
|
||||
import 'models/wallet_txn.dart';
|
||||
|
||||
/// نتيجة الشحن — ثلاثة أنماط: فوري · فاتورة · إعادة توجيه.
|
||||
class TopupResult {
|
||||
const TopupResult({
|
||||
required this.status,
|
||||
this.reference,
|
||||
this.transferTarget,
|
||||
this.instructions,
|
||||
this.redirectUrl,
|
||||
});
|
||||
|
||||
final String status;
|
||||
|
||||
/// مرجع الفاتورة الذي يذكره المستخدم عند التحويل — به تُطابَق رسالة
|
||||
/// المزوّد لاحقاً.
|
||||
final String? reference;
|
||||
|
||||
/// حساب/رقم استلام المستأجر عند هذا المزوّد.
|
||||
final String? transferTarget;
|
||||
|
||||
final String? instructions;
|
||||
final String? redirectUrl;
|
||||
|
||||
bool get isInvoice => reference != null;
|
||||
bool get isInstant => status == 'success';
|
||||
bool get isRedirect => redirectUrl != null;
|
||||
}
|
||||
|
||||
class WalletRepository {
|
||||
WalletRepository(this._api);
|
||||
|
||||
@@ -20,8 +47,51 @@ class WalletRepository {
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
Future<void> topup(num amount) =>
|
||||
_api.post<Map<String, dynamic>>('/wallet/topup', body: {'amount': amount});
|
||||
/// شحن حقيقي عبر `POST /payments/charge`.
|
||||
///
|
||||
/// **لا يزيد الرصيد فوراً.** كليك وشام كاش وزين كاش تعمل بنمط الفاتورة:
|
||||
/// الخادم يولّد مرجعاً ويعرض حساب الاستلام، ثم يحوّل المستخدم، والتسوية
|
||||
/// تصل لاحقاً عبر مطابقة رسالة المزوّد. هذا **نفس مسار سيرو** حرفياً.
|
||||
/// PayMob وحده يرجّع رابط إعادة توجيه، و`cash` وحده فوري.
|
||||
/// شحن **الرصيد التشغيلي** للسائق — نيّة مختلفة عن شحن المحفظة:
|
||||
/// `credit_topup` إيرادٌ يُقيَّد على المستأجر، والخادم يرفضها من غير
|
||||
/// السائق (`payments.service.ts:67`).
|
||||
Future<TopupResult> chargeCredit({
|
||||
required num amount,
|
||||
required String provider,
|
||||
required String currency,
|
||||
}) =>
|
||||
charge(
|
||||
amount: amount,
|
||||
provider: provider,
|
||||
currency: currency,
|
||||
purpose: 'credit_topup',
|
||||
);
|
||||
|
||||
Future<TopupResult> charge({
|
||||
required num amount,
|
||||
required String provider,
|
||||
required String currency,
|
||||
String purpose = 'topup',
|
||||
}) async {
|
||||
final res = await _api.post<Map<String, dynamic>>(
|
||||
'/payments/charge',
|
||||
body: {
|
||||
'amount': amount,
|
||||
'provider': provider,
|
||||
'purpose': purpose,
|
||||
'currency': currency,
|
||||
},
|
||||
);
|
||||
final payment = res['payment'] as Map<String, dynamic>?;
|
||||
return TopupResult(
|
||||
status: payment?['status'] as String? ?? 'pending',
|
||||
reference: res['reference'] as String?,
|
||||
transferTarget: res['transferTarget'] as String?,
|
||||
instructions: res['instructions'] as String?,
|
||||
redirectUrl: res['redirectUrl'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
// ── السحب: خطوتان لا خطوة ────────────────────────────────────────────
|
||||
// `request` يرسل رمزاً **بلا خصم**، و`confirm` هو ما يخصم ويحجز
|
||||
|
||||
Reference in New Issue
Block a user